script脚本 一次使用 Go 语言编写脚本的经历

11/28 10:18:15 来源网站:辅助卡盟网

让我们开始尝试给 Go 脚本添加 Shebang。

第一次幼稚的尝试

我们首先设置一个幼稚的 Shebang 来使用 go run 执行这个脚本。加了 Shebang 之后的脚本看上去是这样的:

#! /usr/bin/env go runpackage main
import ( "fmt" "os")
func main() { fmt.Println("Hello", os.Args[1]) os.Exit(42)}

然后尝试运行一下,输出为:

$ ./example.go/usr/bin/env: ‘go run’: No such file or directory

发生了什么?

Shebang 机制将 go run 整体作为 env 命令的一个参数了,而实际不存在这个命令。输入 which "go run" 也会有类似的错误。

第二次尝试

一个可行的方案是将 Shebang 设置为 #! /usr/local/go/bin/go run。在我们尝试之前,就可以会发现一个问题:go 二进制文件在不同系统路径不同,写死绝对路径会导致脚本无法兼容安装在其他位置的 go。另外一个解决方案是使用 alias gorun="go run" 来创建一个别名,之后就能把 Shebang 修改成 #! /usr/bin/env gorun。使用这种方式,我们需要在运行这个脚本的系统中都设置这个别名。

输出:

$ ./example.gopackage main:example.go:1:1: illegal character U+0023 '#'

解释:从这个输出来看,我们有一个好消息,同时也有一个坏消息,你想先听哪个?我先来说好消息:-)

解决方案

当脚本不包含 Shebang 行时,不同的 Shell 会回退到不同的解析器。Bash 会使用自己来运行脚本,而 zsh 会回退到使用 sh。这给我们提供了一种解决方案,这也是 StackOverflow 上提到的一种解决方案。

由于 // 是 Go 语言中定义的注释,而我们可以使用 //usr/bin/env 来替代 /usr/bin/env(在路径分割符中,// == /),因此第一行可以设置成:

//usr/bin/env go run "$0" "$@"

结果:

$ ./example.go worldHi worldexit status 42./test.go: line 2: package: command not found./test.go: line 4: syntax error near unexpected token `newline'./test.go: line 4: `import ('$ echo $?2

解释:

我们距离成功又近了一步:终于有了正确的输出。但是输出中还包含一些错误,同时状态码也不对。让我们来看下到底发生了什么。正如之前所说的,Bash 没有找到任何 Shebang,因此选择使用 bash ./example.go world 的方式来运行脚本(直接使用该命令会有相同输出,你也可以试下)。非常有意思,直接使用 Bash 来运行 Go 文件 :-) 下一步,Bash 读取脚本的第一行,然后运行该命令:/usr/bin/env go run ./example.go world。之前脚本中的“0”代表第一个参数,因此实际值是我们运行的脚本文件名。“@”表示命令行中的所有参数。在这个例子中会被替换成“world”。到目前位置,使用./example.go world,脚本使用了正确的命令行参数,并输出了正确的值。

    暂无相关资讯
script脚本 一次使用 Go 语言编写脚本的经历