Kotlin Native library for create sub-process and redirect their I/O.
Rust is an excellent language that takes into account both performance and engineering.
In version 1.x, we use the following API to provide the function of creating child processes
fork
of [POSIX api]
CreateChildProcess
of [win32 api]
java.lang.ProcessBuilder
of JVM
In version 2.x, we use the Rust standard library to provide the function of creating child processes.
std::process::Command
of Rust
java.lang.ProcessBuilder
of JVM
It will bring
- More unified API
- Easier to use API
- Performance is still excellent
- Easier to maintain
- Code structure is clearer
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- x86_64-pc-windows-gnu (mingw-w64)
- jvm
- Rust Standard Library 1.69.0 (No support for later versions)
- Kotlin Multiplatform 2.0.10
build.gradle.kts
:
// ……
repositories {
mavenCentral()
}
// ……
dependencies {
// should replace with the latest version
implementation("com.kgit2:kommand:2.x")
}
|
package com.kgit2.kommand |
|
|
|
import com.kgit2.kommand.process.Command |
|
import com.kgit2.kommand.process.Stdio |
|
|
|
fun main() { |
|
Command("ping") |
|
.args(listOf("-c", "5", "localhost")) |
|
.stdout(Stdio.Inherit) |
|
.spawn() |
|
.wait() |
|
} |
|
package com.kgit2.kommand |
|
|
|
import com.kgit2.kommand.process.Command |
|
import com.kgit2.kommand.process.Stdio |
|
|
|
fun main() { |
|
val child = Command("ping") |
|
.args(listOf("-c", "5", "localhost")) |
|
.stdout(Stdio.Pipe) |
|
.spawn() |
|
child.bufferedStdout()?.lines()?.forEach { line -> |
|
println(line) |
|
} |
|
child.wait() |
|
} |
|
package com.kgit2.kommand |
|
|
|
import com.kgit2.kommand.process.Command |
|
import com.kgit2.kommand.process.Stdio |
|
|
|
fun main() { |
|
Command("echo") |
|
.arg("nothing") |
|
.stdout(Stdio.Null) |
|
.spawn() |
|
.wait() |
|
} |
|
package com.kgit2.kommand |
|
|
|
import com.kgit2.kommand.process.Command |
|
import kotlinx.coroutines.Dispatchers |
|
import kotlinx.coroutines.IO |
|
import kotlinx.coroutines.async |
|
import kotlinx.coroutines.runBlocking |
|
import kotlinx.coroutines.withTimeout |
|
import kotlinx.datetime.Clock |
|
|
|
fun main() = runBlocking(Dispatchers.Default) { |
|
// Sleep with regular |
|
val start = Clock.System.now() |
|
val status = Command("sleep").arg("5").status() |
|
println("status: $status elapsed: ${Clock.System.now() - start}") |
|
|
|
// Sleep with timeout detection and timeout determination |
|
val start2 = Clock.System.now() |
|
val child = Command("sleep").arg("5").spawn() |
|
val childJob = async(Dispatchers.IO) { |
|
runCatching { |
|
child.wait() |
|
}.onFailure { |
|
println("child result: $it") |
|
}.getOrNull() |
|
} |
|
runCatching { |
|
withTimeout(3000) { |
|
childJob.await() |
|
} |
|
}.onSuccess { |
|
println("status: $it elapsed: ${Clock.System.now() - start2}") |
|
}.onFailure { |
|
child.kill() |
|
println("status: $it elapsed: ${Clock.System.now() - start2}") |
|
} |
|
|
|
// Sleep with timeout detection and determination that it will not timeout |
|
val start3 = Clock.System.now() |
|
val child2 = Command("sleep").arg("2").spawn() |
|
val childJob2 = async(Dispatchers.IO) { |
|
runCatching { |
|
child2.wait() |
|
}.onFailure { |
|
println("child result: $it") |
|
}.getOrNull() |
|
} |
|
runCatching { |
|
withTimeout(3000) { |
|
childJob2.await() |
|
} |
|
}.onSuccess { |
|
println("status: $it elapsed: ${Clock.System.now() - start3}") |
|
}.onFailure { |
|
child2.kill() |
|
println("status: $it elapsed: ${Clock.System.now() - start3}") |
|
} |
|
|
|
Unit |
|
} |
Full example check kommand-examples/timeout.
Dependency:
- rust toolchain - <= 1.69.0 (https://rustup.rs) (recommend)
- just (install with
cargo install just
)
- cross-compile toolchain
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- x86_64-pc-windows-gnu (mingw-w64)
- docker (optional)
Recommend build all platforms in macOS.
Kotlin Multiplatform gets the most complete support on macOS.
If you are using macOS, you can install the cross-compile toolchain with
Otherwise, you need to install the cross-compile toolchain yourself.
git clone https://github.com/kgit2/kommand.git
Only linux support cross-platform test.
Install Docker Engine
# for x86_64
just linuxX64Test
# for aarch64
just linuxArm64Test
@BppleMan.
@XJMiada.(Original Picture)
Apache2.0 © BppleMan