I want to invoke an external command from Kotlin code. In C/Perl, I would use system() function. In Python, I would use the subprocess module. In Go, I would us
I wanted a few changes from the solution of jkschneider, as it didn't catch the error codes I got from the executed commands. Also I did a few refactorings to get this:
directory exec "git status"
or
directory.execute("git", "commit", "-m", "A message")
I also opted to throw exceptions for error codes and shortened the wait, but that can easily be altered according to taste.
/**
* Shorthand for [File.execute]. Assumes that all spaces are argument separators,
* so no argument may contain a space.
* ```kotlin
* // Example
* directory exec "git status"
*
* // This fails since `'A` and `message'` will be considered as two arguments
* directory exec "git commit -m 'A message'"
* ```
*/
infix fun File.exec(command: String): String {
val arguments = command.split(' ').toTypedArray()
return execute(*arguments)
}
/**
* Executes command. Arguments may contain strings. More appropriate than [File.exec]
* when using dynamic arguments.
* ```kotlin
* // Example
* directory.execute("git", "commit", "-m", "A message")
* ```
*/
fun File.execute(vararg arguments: String): String {
val process = ProcessBuilder(*arguments)
.directory(this)
.start()
.also { it.waitFor(10, TimeUnit.SECONDS) }
if (process.exitValue() != 0) {
throw Exception(process.errorStream.bufferedReader().readText())
}
return process.inputStream.bufferedReader().readText()
}