Kotlin-native: How to execute a command line and get the output?

Created on 11 Aug 2018  路  4Comments  路  Source: JetBrains/kotlin-native

I want to execute a command line and get the output as String or even save it as a new text file.

For example the next command will save the git diff in a new file called output.txt

$ git diff > output.txt

Most helpful comment

Do you know how can we get the output or the error output of the commands?
Also, where I can find the documentation for the platform.posix.system? I'd like to follow from there

All 4 comments

From native application?

platform.posix.system("git diff > output.txt")

@msink
Yes, for a native application, that works with me.
THANK YOU! 馃憤

Do you know how can we get the output or the error output of the commands?
Also, where I can find the documentation for the platform.posix.system? I'd like to follow from there

I played around with kotlin native and succeeded to execute arbitrary processes (using https://www.javaer101.com/en/article/35619482.html)

here's my result:

https://github.com/hoffipublic/minimal_kotlin_multiplatform

import kotlinx.cinterop.refTo
import kotlinx.cinterop.toKString
import platform.posix.fgets
import platform.posix.pclose
import platform.posix.popen

actual object MppProcess : IMppProcess {
    actual override fun executeCommand(
        command: String,
        redirectStderr: Boolean
    ): String? {
        val commandToExecute = if (redirectStderr) "$command 2>&1" else command
        val fp = popen(commandToExecute, "r") ?: error("Failed to run command: $command")

        val stdout = buildString {
            val buffer = ByteArray(4096)
            while (true) {
                val input = fgets(buffer.refTo(0), buffer.size, fp) ?: break
                append(input.toKString())
            }
        }

        val status = pclose(fp)
        if (status != 0) {
            error("Command `$command` failed with status $status${if (redirectStderr) ": $stdout" else ""}")
        }

        return stdout
    }
}

on jvm

import java.util.concurrent.TimeUnit

actual object MppProcess : IMppProcess {
    actual override fun executeCommand(
        command: String,
        redirectStderr: Boolean
    ): String? {
        return runCatching {
            ProcessBuilder(command.split(Regex("(?<!(\"|').{0,255}) | (?!.*\\1.*)")))
                //.directory(workingDir)
                .redirectOutput(ProcessBuilder.Redirect.PIPE)
                .apply { if (redirectStderr) this.redirectError(ProcessBuilder.Redirect.PIPE) }
                .start().apply { waitFor(60L, TimeUnit.SECONDS) }
                .inputStream.bufferedReader().readText()
        }.onFailure { it.printStackTrace() }.getOrNull()
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

brettwillis picture brettwillis  路  4Comments

talanov picture talanov  路  3Comments

9468305 picture 9468305  路  3Comments

jonnyzzz picture jonnyzzz  路  4Comments

Marcopohlo picture Marcopohlo  路  4Comments