输出中还有诡异的一行:“exit status 42”。这是什么?如果我们自己尝试下命令就会了解:
$ go run ./example.go world
Hello world
exit status 42
$ echo $?
1
这是 go run 命令通过标准错误输出的。go run 命令屏蔽了状态码,然后返回了状态码 1。关于这个行为的讨论,可以参见 Github issue。
好了,那么其他几行输出呢?这是 Bash 试图解析 Go 源码,但实际失败了。
解决方案优化
这个 StackOverflow 页面建议在 Shebang 之后加上 ;exit “$?”。这会告诉 Bash 解释器不要再继续执行。
完整的 Shebang:
//usr/bin/env go run "$0" "$@"; exit "$?"
结果:
$ ./test.go world
Hi world
exit status 42
$ echo $?
1
基本上实现了:这里实现了让 Bash 使用 go run 命令执行脚本script脚本,然后立即退出,同时设置状态码为 go run 命令执行后的状态码。
更进一步,可以在 Shebang 行中添加一些命令,用于移除标准错误中的“退出状态”内容,甚至解析该文本并作为整个脚本的返回码。
然而:
5 幸运的是,我们有 gorun
gorun 就是我们想要的。我们只需在 Shebang 中写 #! /usr/bin/env gorun,并赋予脚本可执行权限。仅此而已,我们可以在 Shell 中执行,获得期望的结果!
$ ./example.go world
Hello world
$ echo $?
42
太棒了!
警告:兼容性
当文件包含 Shebang 之后,Go 将无法编译(和我们之前看见的一样)。
$ go run example.go
package main:
example.go:1:1: illegal character U+0023 '#'
这两种选择不能兼得,我们只能二选一:
二者不可兼得!
另外一个问题,是当脚本文件被放在 Go 工程中时script脚本,编译器会发现这个 go 文件。虽然该文件并不是应用程序所需要的,也会导致编译失败。一个解决方案是移除.go 后缀,但是这样就会无法使用类似 go fmt 等工具。
6 最后一些想法
本文讨论了使用 Go 语言来编写脚本的重要性,同时介绍了几种方式来实现脚本运行。这里有一些总结。
解释:
正如上表,目前没有一种完美的解决方案。看上去最方便且问题最少的方式是使用 go run 命令。但是在我看来,这种方式太过“复杂”,而且无法“可执行”辅助卡盟,同时退出状态码也不正确。这将会导致难以区分脚本是否正确执行。
因此,我认为 Go 语言在这个领域仍然有许多工作要做。我不认为让语言支持忽略 Shebang 行会有什么问题。这将会解决执行问题,但是类似这种变化可能不会被 Go 社区采纳。
我的同事提醒我事实上 Shebang 行对于 Javascript 同样也是非法的。但是在 Node.js 中,他们增加了一个跳过 Shebang 函数,让 Node 脚本可以在 Shell 中直接运行。(译者注:由于原文时间比较久远,在 c2b01881dcb3bf302f9d83157e719cc5240a9042 版本之后 Node.js 已经对源码进行了重构,在 702331be906fe58e0ef66c7b31c7d2aeb3af3421 版本之后,原文提及的 stripShebang 函数已经被移除。)
如果 gorun 可以作为标准工具的一部分就更棒了,其他类似的还有 gofmt 和 godoc。
原文链接:
点个在看少个 bug
来源:【九爱网址导航www.fuzhukm.com】 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!