Go 作为一种可用于创建高性能网络和并发系统的编程语言,它的生态应用变得越来越广泛[1],同时,这也激发了开发人员使用 Go 作为脚本语言的兴趣。
扫描下方二维码,备注:go语言笔记视频,免费领取~
基本上,我一直在编写 Go 程序,偶尔会写写 Bash、perl 和 python 。有时候,这些编程语言会落入我的脑海。
go run
是 Go 构建工具链中的默认命令,能够一步一步地编译和运行 Go 程序。Posener 写道:“事实上,go run
并非作为解释器来使用。”[...] bash 和 python 都是解释型语言 —— 它们在读取脚本的时候,然后执行脚本文件。另一方面,当您键入 go run
时,Go 编译器就会编译程序,然后运行它们。Go 程序的编译时间很短,这使它看起来就像是解释型语言一般。
github.com/fatih/color[8] 是用于输出对应编码颜色的包。 github.com/schollz/progressbar[9] 是用于为执行时间过久的任务创建进度条的包。 github.com/jimlawless/whereami[10] 是用于捕获源代码的文件名、行号、函数等信息的包,这对于改正错误信息十分有用! github.com/spf13/cobra[11] 是用于更轻松地创建带有输入选项和相关文档的复杂脚本的包。
go run
来运行 Go 程序非常有效,但是它并非最完美的解决方案。”Shebang
( 译者注:Unix 系统中,通常称 #
为 sharp
或 she
;而称 !
为 bang
) 集成在一起,这使得脚本可以像二进制程序一样执行。此外,比起短小精悍的脚本文件,Go 错误处理更适合大型程序项目使用。Neugram
类似的方法,它是一种 Go 的解释器,还支持类似 Lisp 的宏,既可以生成代码,又可以实现某种形式的泛型[15]。Gomacro
几乎是一个完整的 Go 解释器,它使用纯 Go 语言实现。它提供了交互式的REPL
模式和脚本模式,并且在运行时不需要 Go 构建工具链。(除了在在一种非常特殊的情况以外:在运行时导入第三方包。)
Gomacro
还旨在使得 Go 成为一种中间语言,表示要将它解释为 Go 的标准详细规范[16],还会提供 Go 源代码的调试器[17]。Gomacro
为其提供了最大灵活性,但不幸的是,它不是标准的 Go 语言,这引起了另一种程度的担忧。Shebang
的解决方法。但是,这些解决方法都在某种程度上均有不足的体现。似乎没有完美的解决方案,而且我也不明白为什么不能有一个完美的解决方案。看起来,运行 Go 脚本的方式最为简单,而最没有问题的方法就是使用 go run
命令。[...] 这就是我为什么认为在该语言领域上,仍需要做未完成的工作。同样的,我认为更改程序语言用来忽略Shebang
不会有任何的危害。
Shebang
支持的情况下,从命令行运行 Go 脚本。Shebang
对 Linux 内核的支持,以及从 Linux 用户空间扩展受到支持二进制格式的可能性。长话短说,Korchagin 建议使用以下方式注册二进制:$ Echo ':golang:E::go::/usr/local/bin/gorun:OC' | sudo tee /proc/sys/fs/binfmt_misc/register
:golang:E::go::/usr/local/bin/gorun:OC
package main
import (
"fmt"
"os"
)
func main() {
s := "world"
if len(os.Args) > 1 {
s = os.Args[1]
}
fmt.Printf("Hello, %v!", s)
fmt.Println("")
if s == "fail" {
os.Exit(30)
}
}
$ chmod u+x helloscript.go
$ ./helloscript.go
Hello, world!
$ ./helloscript.go gopher
Hello, gopher!
$ ./helloscript.go fail
Hello, fail!
$ Echo $?
30
尽管这种方法无法提供对 REPL
的支持,但是 Shebang
可能足以满足典型的用例。
作者:Sergio De Simone[19]译者:sunlingbot[20]校对:polaris1119[21]
本文由 GCTT[22] 原创编译,Go 中文网[23] 荣誉推出
参考资料
越来越广泛: https://blog.golang.org/survey2019-results
[2]正如来自 Codelang 的 Elton Minetto 所说的那样: https://dev.to/codenation/using-golang-as-a-scripting-language-jl2
[3]Eyal Posener: https://posener.github.io/about/
[4]更多的理由: https://gist.github.com/posener/73ffd326d88483df6b1cb66e8ed1e0bd
[5]强调了使用 Go 编写脚本任务的便利程度: https://news.ycombinator.com/item?id=15623106
[6]帮助 Go 脚本变得更加可靠,并且避免出现像拼写之类的小错误,从而不会出现发生在运行时的报错: https://blog.cloudflare.com/using-go-as-a-scripting-language-in-linux/
[7]go run
: https://golang.org/cmd/go/#hdr-Compile_and_run_Go_program
github.com/fatih/color: https://github.com/fatih/color
[9]github.com/schollz/progressbar: https://github.com/schollz/progressbar
[10]github.com/jimlawless/whereami: https://github.com/jimlawless/whereami
[11]github.com/spf13/cobra: https://github.com/spf13/cobra
[12]Neugram: https://github.com/neugram/ng
[13]由于 Go 语法的所有细节的复杂性: https://news.ycombinator.com/item?id=15623244
[14]Gomacro: https://github.com/cosmos72/gomacro
[15]泛型: https://github.com/cosmos72/gomacro#generics
[16]解释为 Go 的标准详细规范: https://github.com/cosmos72/gomacro/blob/master/doc/code_generation.pdf
[17]提供 Go 源代码的调试器: https://github.com/cosmos72/gomacro#debugger
[18]Posener 对使用标准的 Go 语言作为脚本语言的可能性进行了详细分析: https://gist.github.com/posener/73ffd326d88483df6b1cb66e8ed1e0bd
[19]Sergio De Simone: https://www.infoq.com/profile/Sergio-De-Simone/
[20]sunlingbot: https://github.com/sunlingbot
[21]polaris1119: https://github.com/polaris1119
[22]GCTT: https://github.com/studygolang/GCTT
[23]Go 中文网: https://studygolang.com/