Overview
- Bash is the most widely used and familiar script interpreter for system engineers and developers in the operating environment, but it also offers the most uncomfortable scripting language. Over the years, the development community has seen languages that ensure Type-Safety dominate in terms of productivity and maintenance, with TypeScript in the frontend and
Kotlin
in the backend increasing their market share. So, what about writing shell scripts with Kotlin? Node.js is already widely used for shell scripting. In this article, we will explain how to write shell scripts with Kotlin.
Installing kscript
kscript
is a useful auxiliary tool that allows you to write shell scripts in Kotlin language. It provides several useful tools, including script cache to overcome the disadvantages of JVM. Install it as follows.
$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
$ sdk install kotlin
$ sdk install kscript
$ kscript -v
Version : 4.2.3
Build : 2023-07-22T13:06:02.327407526Z
Kotlin : 1.9.23-release-779
Java : JRE 21.0.1+12
Writing a kscript Example
- Now it's time to write a script.
$ nano hello.kts
println("Hello, World!")
$ chmod +x hello.kts
$ ./hello.kts
Hello, World!
$ kscript --idea hello.kts
Adding a Library Example
- You can use remote libraries from the Maven repository at the beginning of the script by using
@
file:DependsOn()
. Below is an example of importing and using the TSID class from an external library.
$ nano tsid.kts
@file:DependsOn("io.hypersistence:hypersistence-utils-hibernate-60:3.7.3")
import io.hypersistence.tsid.TSID
val tsid = TSID.fast()
println(tsid.toLong())
println(tsid.toString())
println(tsid.toLowerCase())
println(tsid.instant)
Executing External Commands Example
- By writing a script as follows, you can execute external commands within the script.
#!/usr/bin/env kscript
import java.io.File
when ("ls -al".exec()) {
0 -> println("SUCCESS")
else -> {
println("FAILED")
kotlin.system.exitProcess(1)
}
}
fun String.exec(cwd: File? = null): Int {
return ProcessBuilder(*split(" ").toTypedArray())
.redirectErrorStream(true)
.inheritIO()
.directory(cwd)
.start()
.waitFor()
}
fun String.exec(cwd: File? = null): String? {
val parts = this.split("\s".toRegex())
val proc = ProcessBuilder(*parts.toTypedArray())
.directory(cwd)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start()
proc.waitFor()
return proc.inputStream.bufferedReader().readText()
}
References