作为一个Java或者Android开发者,有时候需要写脚本代码,经常性的为了如何写shell脚本查询各个命令的使用,以及shell的语法规则。 shell嘛毕竟不是一个高级语言,写起来对于不熟悉shell命令和语法的人来说确实很麻烦,但是不得不说shell的执行效率是非常高效的。如果你也遇到和我相同的问题,那么赶快转型Kotlin酣畅淋漓的写脚本吧。

Kotlin在1.3.70版本之后,支持了运行命令行脚本的能力。

1
2
3
#! /usr/bin/env kotlin

println("hello kotlin script")

为什么要用Kotlin Script写脚本

  • 环境搭建So Easy

  • 可读性比Shell强太多

  • IDE 支持 (IntelliJ IDEA),语法突出显示/错误等

  • 可以直接使用现有的Java或Kotlin三方库

  • 代码共享So Easy

环境准备

环境准备,只需要有kotlinc编译器就可以,具体有两种方式:安装Kotlin Command-line Compiler 或者直接使用IDE工具(IDEA / Android Studio)

  • Kotlin Command-line Compiler 安装

    Mac系统推荐使用homebrew安装, 其他操作系统参考一下官方链接

1
2
3
4
5
6
# Mac OS 安装
brew install kotlin
# 检查环境变量配置是否正确
kotlin -version

Kotlin version 1.9.21-release-633 (JRE 11.0.19+7-LTS)
参考文档:   [Kotlin command-line compiler | Kotlin Documentation](https://kotlinlang.org/docs/command-line.html)
  • IntelliJ IDEA/ AndroidStudio 下载安装即可

First Kotlin Script

  1. 创建一个后缀为.main.kts的文本文件,例如hello-world.main.kts, 将脚本环境设置为kotlin

    1
    #!/usr/bin/env kotlin
  2. 书写Kotlin 代码

    1
    2
    3
    #!/usr/bin/env kotlin

    println("hello world, from kotlin script!!")
  3. 运行脚本

    1
    2
    3
    4
    kotlin hello-world.main.kts

    # Output
    hello world, from kotlin script!!

完成这三部,最简单的kotlin脚本已经完成了。Kotlin Script最厉害的地方是你可以使用高级语言的特性,以及可以使用现有的Java/Kotlin库。 下面我们看一下他厉害的功能吧

命令行参数传递

类似于其他脚本语言,kotlin script可以接收来自命令行的参数,方式非常简单,所有的命令行参数均被存储在args对象中,它是一个Array类型的变量。例如:打印所有的命令行参数的脚本:test-args.main.kts

1
2
3
4
5
6
7
8
9
#!/usr/bin/env kotlin

if (args.isEmpty()) {
println("No command line arguments")
} else {
for (arg in args) {
println(arg)
}
}

执行脚本:

1
2
3
4
5
6
kotlin test-args.main.kts arg1, arg2, end

#Output
arg1
arg2
end

Kotlin脚本文件之间的相互引用

kotlin脚本支持多个脚本之间相互引用,方式也非常简单:

1
@file:Import("<file1>", "<file2>", "<file3>")

例如引用一个工具脚本comm-util.main.kts的例子

1
2
3
4
5
6
#!/usr/bin/env kotlin
@file:Import("comm-util.main.kts")

println("test utils")
#直接调用comm-util.main.kts中的方法
executeCommandOnShell("ls")

common-utils.main.kts代码如下

1
2
3
4
5
6
#!/usr/bin/env kotlin

fun executeCommandOnShell(command: String) {
val process = ProcessBuilder(command).inheritIO().start()
process.waitFor()
}

Kotlin Script引用三方库

Kotlin Script支持直接引用三方库,这能让我们快速的完成代码编写,降低了开发复杂度。

它可以支持从maven仓库获取三方代码库进行下载,并在脚本中直接应用。例如可以使用它直接从maven仓库下载gson,okhttp等开源库,进行json或者网络操作, 方式如下:

1
2
3
4
// 链接存储库
@file:Repository ( "<repository-link1>" , "<repository-link2>" , "<repository-link3>" )
// 库依赖配置
@file:DependsOn ( "<group-id :artifact-id:version>" , "<group-id:artifact-id:version> " , "<group-id:artifact-id:version>" )

Demo如下:使用gson进行json操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env kotlin
@file:Repository("https://repo.maven.apache.org/maven2/")
@file:DependsOn(
"com.squareup.okio:okio:3.6.0",
"com.google.code.gson:gson:2.10.1"
)

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import okio.FileSystem
import okio.Path.Companion.toPath
import okio.buffer
import java.lang.StringBuilder

data class Item(val key1: String, val key2: String)
class Items(val items: Array<Items>)

fun readFile(fileName: String): String {
val fileContent = StringBuilder()
FileSystem.SYSTEM.source(fileName.toPath()).use { fileSource ->
fileSource.buffer().use { bufferedFileSource ->
while (true) {
val line = bufferedFileSource.readUtf8Line() ?: break
fileContent.append(line)
}
}
}
return fileContent.toString()
}

val fileData = readFile("sample.json")
val typeToken = object : TypeToken<List<Item>>() {}.type
val items = Gson().fromJson<List<Item>>(fileData, typeToken)
println(items)

IDE支持

对于任何编程语言来说,重要的事情之一就是工具支持以及它如何使开发人员能够轻松地用该语言编写代码和构建软件。IntelliJ IDEA 对 Kotlin 脚本有很好的支持。它为 Kotlin API 和导入的依赖项提供自动完成功能,支持自动导入、显示编译错误、验证依赖项路径等。这使得在 Kotlin 中编写脚本变得更加容易。

IntelliJ IDEA 进行脚本编写

  1. 新建项目进行脚本书写:

    • 使用IDEA创建一个Empt工程

    • 设置项目SDK为Java即可

2- 在现有的Kotlin/Java/Android工程中书写脚本

  • 在项目中任意位置,创建.main.kts脚本即可

团队共享

由于需要kotlinc进行编译,团队共享时,如果有人没安装kotlinc,则无法运行脚本,为了解决这个问题,可以将kotlinc和脚本一起进行共享,通过shell脚本进行暴露重定向到kotlin脚本:例如,start.sh脚本,内容如下:

1
2
3
#!/usr/bin/env bash
#./kts/hello.main.kts $dirPath $*
./kts/kotlinc/bin/kotlin ./kts/review/hello.main.kts $*

执行脚本时,只需要运行start.sh脚本即可