Home > Back-end >  Kotlin script to run os command and parse output
Kotlin script to run os command and parse output

Time:11-22

Preface this by saying i'm entirely new to Kotlin but it's time that i start understanding this thing.

I have a command that i run in powershell.

kubectl get pods -o jsonpath='{range .items[*]}{.spec.containers[].image}{\"\n\"}{end}'

I want to create a kotlin script to run that command and then parse the output in kotlin as a string using something in kotlin like a Java string tokenizer.

At this stage I'm using kotlin scripting and have a basic hello world working like below. The only reason I'm listing this in the question is bc I want to stick to a simple kotlin script and want to make that clear:

println("Called with args:")
args.forEach {
    println("- $it")
}

RUN AND OUTPUT OF SCRIPT
kotlinc -script .\helloScript.kts hello
Called with args:
- hello

Can someone help me with how this might be best coded in Kotlin script? I've done some research but am finding it hard to find the right example that suits what i'm after.

thanks!

CodePudding user response:

I did not test it, but along this (on the JVM):

val command = arrayOf(
  "kubectl",
  "get",
  "pods",
  "-o",
  "jsonpath='{range .items[*]}{.spec.containers[].image}{\"\n\"}{end}'"
)

Runtime.getRuntime()
  .exec(command)
  .waitFor()   // this line only if necessary

Or if there is a return value (one line in this case):

val text = Runtime.getRuntime()
  .exec(command)
  .inputStream
  .bufferedReader()
  .readLine()
  .orEmpty()
  .trim()

CodePudding user response:

I've accepted an answer here already because it helped me but just for completeness after having some fun playing around here is what i ended up with that was working by the time i got through with it. thanks all

import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStream
import java.nio.charset.Charset
import java.util.ArrayList
import java.util.HashMap
import kotlin.text.Charsets.UTF_8


val command = "kubectl get pods"

execLocal(command)

    fun execLocal(command: String): String {
        try {
            val commands = ArrayList<String>()
            commands.add("powershell.exe")
            commands.add("-Command")
            commands.add(command)

            val pb = ProcessBuilder(commands)
            
            println("Running: "   pb.command())

            val process = pb.start()
            val result = collectOutput(process.inputStream)

            if (process.waitFor() != 0) {
                println("Failed to execute command: "   pb.command())
                println("Result: "   result)
                throw RuntimeException()
            } else {
                println("stdout: "   result)
            }
            return result
        } catch (e: IOException) {
            throw RuntimeException(e)
        } catch (e: InterruptedException) {
            throw RuntimeException(e)
        }
    }

    fun collectOutput(inputStream: InputStream): String {
        val out = StringBuilder()
        val buf: BufferedReader = inputStream.bufferedReader(UTF_8)
        var line: String? = buf.readLine()
        do {
            if (line != null) {
                out.append(line).append("\n")
            }
            line = buf.readLine()
        } while (line != null)
        return out.toString()
    }
  • Related