用Go语言编写脚本的经历

通常认为,Python 和 Bash 是热门的脚本语言,而 C、C++ 和 Java 完全不能被用作脚本编程,有一些语言却夹在其中。Go 语言试用场景很多,从编

大家好,关于用Go语言编写脚本的经历很多朋友都还不太明白,今天小编就来为大家分享关于的知识,希望对各位有所帮助!

Go语言的试用场景有很多,从编写Web服务器到进程管理,甚至有人将其作为系统编程语言。在下面的文章中,我将论证除了这些场景之外,Go语言还可以简单地用于编写脚本。

是什么让Go 语言适合编写脚本?

Go 语言简洁,易于阅读,而且不太冗长。这使得编写的脚本易于维护并且相对较短。 Go 语言有许多可用于各种目的的库。假设这些库稳定且经过测试,这可以使脚本保持简洁和健壮。如果我的大部分代码都是用Go 编写的,那么我更愿意使用Go 作为我的脚本语言。当代码由许多人协作维护时,通过使用每个人都可以完全控制的语言来降低维护成本,即使它只是几个脚本。

Go 语言已经 99% 支持脚本

事实上,我已经可以用Go 编写脚本了。这需要使用Go的run子命令:如果脚本名称是my-script.go,我们可以简单地通过go run my-script.go来运行它。

这里,我觉得我们需要特别注意一下go run命令。让我们详细说明一下。

Go语言与Bash和Python的区别在于后者是通过解释执行的,即它们的脚本被读取时就被执行。对于Go语言来说,当用户输入go run时,Go会编译Go程序,然后执行。因为Go 编译速度非常快,所以看起来像是解释执行。值得提醒的是,很多人说“go run 只是一个玩具”,但如果我们需要脚本并且也喜欢Go 语言,那么这个玩具就是我们想要的。

所以已经支持的很好了,对吧?

我们可以编写脚本并通过go run 命令执行它们。有哪些疑问?问题是我很懒,想通过./my-script.go 之类的东西来运行脚本,而不是go run my-script.go 。

这里我们讨论一个简单的脚本,它以两种方式与shell 交互:它从命令行获取输入数据并设置退出状态代码。这两者并不是所有可能的交互方式(此外还可以有环境变量、信号、stdin、stdout、stderr等),但它们是shell脚本中比较困难的两种方式。

此脚本打印“Hello”和从命令行获取的第一个参数,并将退出状态代码设置为42:

package main import ( ‘fmt’ ‘os’) func main() { fmt.Println(‘Hello’, os.Args[1]) os.Exit(42)} 这时候使用go run 命令会出现一些结果奇怪的:

$ go run example.go worldHello worldexit status 42$ echo $?1 我们稍后会讨论这个问题。

这时候就可以使用go build命令了。这是通过go build 命令执行脚本的方式:

$ go build$ ./example worldHello world$ echo $?42 此时,调试脚本的流程变为:

$ vim ./example.go$ go build$ ./example.go worldHi world$ vim ./example.go$ go build$ ./example.go worldBye world 我期望实现的是运行这样的脚本:

$ chmod +x example.go$ ./example.go worldHello world$ echo $?42 对应的工作流程为:

用Go语言编写脚本的经历

$ vim ./example.go$ ./example.go worldHi world$ vim ./example.go$ ./example.go worldBye world 似乎是一个简单的答案,对吗?

Shebang

Shebang 在类UNIX 系统上受支持。 Shebang 用于告诉shell 使用什么解释器来运行脚本。我们可以根据脚本编写的语言来设置Shebang 行。

一般来说,我们会使用env命令作为脚本执行器,这样我们就不再需要使用解释器的绝对路径了。例如:您可以将Shebang 设置为#!/usr/bin/env python 让Python 解释器运行脚本。当名为example.py 的脚本具有上述Shebang 行并且具有可执行属性(可以使用chmod +x example.py 命令添加)时,可以通过在Shell 中输入./example.py arg1 arg2 来运行它。此时Shell会读取Shebang行,然后开始连锁反应:

shell 开始运行/usr/bin/env python example.py arg1 arg2。这本质上是Shebang 行加上脚本名称加上其他参数。该命令执行/usr/bin/env,参数为/usr/bin/env python example.py arg1 arg2。然后env命令调用python命令,执行python example.py arg1 arg2。最后,python运行example.py脚本,参数为example.py arg1 arg2。

让我们首先尝试将Shebang 添加到我们的Go 脚本中。

1. 第一次天真的尝试

我们首先设置一个简单的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’ : 没有这样的文件或目录发生了什么?

Shebang机制使用go run作为env命令的参数,但这个命令实际上并不存在。输入“go run”会出现类似的错误。

2.第二次尝试

一个可能的解决方案是将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: 非法字符U+0023 ‘#’ 解释:

从这个输出来看,我们有好消息也有坏消息。你想先听哪一个?先告诉你一个好消息:-)

用Go语言编写脚本的经历

好消息是这个解决方案是成功的,执行脚本后正常调用了go run命令。坏消息:英镑符号。在许多脚本语言中,Shebang 开头的井号作为注释被忽略。但对于Go语言编译器来说,前导井号变成了“非法字符”。 3、解决方案

当脚本不包含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: 命令未找到。/test.go: line 4: 意外标记`newline’ 附近出现语法错误。/test.go: line 4: `import (‘$ echo $ ?2说明:

输出中还有一行奇怪的内容:“exit status 42”。这是什么?如果我们自己尝试一下命令我们就会明白:

$ go run ./example.go worldHello worldexit status 42$ echo $?1这是go run 命令通过标准错误输出的内容。 go run 命令屏蔽状态代码并返回状态代码1。有关此行为的讨论,请参阅Github 问题。

好的,那么其他输出行呢?这是Bash 试图解析Go 源代码,但实际上失败了。

4、方案优化

此StackOverflow 页面建议添加;exit “$?”在谢邦之后。这告诉Bash 解释器不要继续执行。

完整的舍邦:

//usr/bin/env go run ‘$0’ ‘$@’;退出“$?”结果:

$ ./test.go worldHi worldexit status 42$ echo $?1 基本实现了:这里Bash使用go run命令执行脚本,然后立即退出,并将状态码设置为go run命令后的状态码被执行。

更进一步,您可以向Shebang 行添加命令,从标准错误中删除“退出状态”内容,甚至将该文本解析为整个脚本的返回代码。

然而:

添加更多的Bash 命令意味着冗长的Shebang 行,与最初期望的#!/usr/bin/env go 相比过于复杂。请记住,这只是一个黑客,我不喜欢黑客。毕竟我们只想使用标准的Shebang 机制。为什么?因为它是如此简单、标准、优雅。这或多或少是我想找到一种更方便的语言作为脚本语言(比如Go)来替代Bash 的原因。幸运的是,我们有gorun

用Go语言编写脚本的经历

gorun 就是我们想要的。我们只需要在Shebang中写入#!/usr/bin/env gorun,并赋予脚本可执行权限即可。就这样,我们就可以在Shell中执行它并得到想要的结果了!

$ ./example.go worldHello world$ echo $?42 太棒了!

警告:兼容性

当文件包含shebang 时,Go 将不会编译(正如我们之前看到的)。

$ go run example.gopackage main:example.go:1:1:非法字符U+0023 ‘#’ 不能同时有两个选项,我们只能选择其一:

使用Shebang 并通过./example.go 运行脚本。或者删除Shebang 并使用go run ./example.go 运行脚本。你不能两者兼得!

最后一些想法

类型退出状态代码可执行可编译标准go rungorun //解决方案

解释:

类型:如何运行脚本。退出状态码:脚本执行后,是否设置脚本的退出状态码。可执行:脚本是否可以通过chmod +x设置可执行权限。 Compilable:脚本是否可以通过go构建。标准:脚本是否需要标准库之外的任何内容。如上图所示,目前还没有完美的解决方案。看来最方便、问题最少的方式就是使用go run 命令。但在我看来,这个方法太“复杂”且不“可执行”,而且退出状态码不正确。这将使得很难判断脚本是否正确执行。

所以我认为Go语言在这方面还有很多工作要做。我不认为让语言支持忽略Shebang 行有什么问题。这将解决实现问题,但这样的更改可能不会被Go 社区采用。

我的同事提醒我,Shebang 行实际上对于Javascript 来说也是非法的。但在Node.js中,他们添加了skip Shebang功能,以便Node脚本可以直接在Shell中运行。 (译者注:由于原文已相当旧,Node.js在c2b01881dcb3bf302f9d83157e719cc5240a9042版本之后重构了源码。702331be906fe58e0ef66c7b31c7d2aeb3af3421版本之后,原文中提到的stripShebang函数已被删除。)

如果gorun 能够与gofmt 和godoc 一起成为标准工具的一部分,那就太好了。

原文链接:

用户评论

用Go语言编写脚本的经历
墨染年华

刚开始接触Go,感觉简洁明了,比之前用的python快很多!这次写脚本真的体验感好,编译速度也飞快,简直太棒了!

    有10位网友表示赞同!

用Go语言编写脚本的经历
一笑傾城゛

虽然Go 的语法简单,但是对于我来说还是有些新奇的地方需要慢慢学习摸索。不过这个脚本写的思路很清晰,读起来还行,可以借鉴一下。

    有14位网友表示赞同!

用Go语言编写脚本的经历
花海

第一次用Go语言写脚本挺有趣儿,感觉比其它語言容易上手不少,尤其是数据处理和并发部分,Go确实很有优势,打算以后多利用它来写一些小的工具.

    有20位网友表示赞同!

用Go语言编写脚本的经历
仅有的余温

这篇文章写的不错,介绍的Go语言的优缺点比较全面,让我对Go语言有了更深入的理解。我正在学习Go语言,这篇blog对我来说很实用!

    有15位网友表示赞同!

用Go语言编写脚本的经历
将妓就计

感觉Go 的语法还是比较简洁易懂的,但对于新手来说,环境配置和工具链可能稍微有些复杂。总体来说脚本写得还不错,思路清晰可读性强。

    有9位网友表示赞同!

用Go语言编写脚本的经历
凉月流沐@

Go 的性能一直是被吹捧的优势,但这篇文章中关于Go语言编写脚本的体验描述更像是在歌颂它的简单易用性。确实,Go 对于快速开发这种小型脚本很有帮助,但并不是说它适合所有类型的脚本编写场景, 还是得根据实际情况选择合适的工具。

    有18位网友表示赞同!

用Go语言编写脚本的经历
堕落爱人!

脚本写的真的很有深度,虽然我目前还没接触过Go语言,但是阅读代码逻辑能清晰地理解作者的思路。学习语言的过程确实需要不断实践和尝试,期待有一天我也能写出像这样实用的代码!

    有18位网友表示赞同!

用Go语言编写脚本的经历
墨城烟柳

对于已经熟悉多种语言的程序员来说,Go 语言并不算难上手,这篇博客里提到的 Golang 特点和使用体验非常实用,对正在学习Go语言的朋友们很有帮助!

    有6位网友表示赞同!

用Go语言编写脚本的经历
黑夜漫长

我觉得 Go 语言在性能稳定性方面确实很优秀,但对于一些需要频繁交互或者调用的脚本功能来说,它可能显得有些笨重。当然这得看项目需求了。

    有10位网友表示赞同!

用Go语言编写脚本的经历
那伤。眞美

文章写的非常详细,将Go语言编写脚本的过程和需要注意的地方都描述了很清楚, 对于初学者来说很有帮助!

    有10位网友表示赞同!

用Go语言编写脚本的经历
折木

感觉文章描述的Go语言的优势有点过分宣传了,实际应用中,总有一些局限性。比如对于一些需要高度定制化的场景,Go语言可能不够灵活。

    有13位网友表示赞同!

用Go语言编写脚本的经历
苏樱凉

第一次尝试用Go语言编写脚本,感觉它的类型系统很有帮助。代码写的更加清晰易懂,维护起来也更方便!

    有9位网友表示赞同!

用Go语言编写脚本的经历
﹎℡默默的爱

我是一个Python开发者,一直在寻找一种性能更高的方式来实现我的脚本任务。最近开始学习 Go 语言,这本书提供了很好的入门指南, 文章中涉及的例子也十分实用.

    有10位网友表示赞同!

用Go语言编写脚本的经历
柠栀

Go语言确实很强大,但对于一些需要大量调用外部API的任务来说,他的缺点可能更为明显。比如,Go的HTTP库相比Python中的requests库功能相对较少。需要开发者自己去拼凑实现, 整体开发效率可能会降低。

    有10位网友表示赞同!

用Go语言编写脚本的经历
相知相惜

我觉得脚本写的不错, 但Go语言的并发机制对新手来说有点复杂, 需要多加练习才能真正理解和掌握。

    有8位网友表示赞同!

用Go语言编写脚本的经历
泡泡龙

这篇博客分享的可视化效果真的很棒!用图表展示Go语言使用场景和特点,让文章内容更生动有趣, 帮助读者快速掌握关键信息。

    有20位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/175252.html

(0)
小su's avatar小su
上一篇 2024年9月22日 上午9:13
下一篇 2024年9月22日 上午9:19

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注