到目前为止,我们所有的脚本都是用 Bash 编写的,但我开始觉得这样做有点傻。虽然我们当然可以用 Bash 做任何我们想做的事情(它非常强大),但我开始怀疑我们是否应该使用一种合适的脚本语言(在我们的情况下最有可能是 Ruby)。
如何决定何时使用 Perl/Python/Ruby 而不是 Bash 编写脚本?我认为使用 Ruby 编写初始化脚本没有意义,但是添加电子邮件帐户的稍长脚本怎么样?
答案1
如果遇到两者都能解决的问题,那么你应该使用你最熟悉的那个。归根结底,还有很多小细节,只有经验才能教会你看清它们。
Bash 是一种通用脚本语言,就像 Python、Ruby、Perl 一样,但每种语言都比其他语言有各自的优势。Perl 擅长文本分析,Python 号称是其中最优雅的,Bash 脚本擅长“管道传输内容”,如果你明白我的意思,那么 Ruby... 嗯,Ruby 在很多方面都有点特别。
但是,只有当您拥有丰富的脚本编写经验后,它们之间的差异才真正重要。我建议您先选择一种语言,然后将其发挥到极致,然后再转到另一种语言。您可以在 shell 脚本中做很多事情,比大多数人承认的要多。任何语言的难度都取决于您想让它变得有多难。在您用它编写了几段代码之后,每种语言对您来说都是“容易”的。
如果您使用 Linux,那么熟悉 shell 会很快给您带来回报,因此您可能想从 Linux 开始。如果您发现某个任务无法或不切实际地在 shell 脚本中解决,请使用其他脚本。
另外,请记住,学习 shell 脚本非常简单。它的真正威力在于其他程序,如 awk、sed、tr 等。
答案2
TL;DR-使用 bash仅有的安装更好的语言(如果尚未提供),否则您将浪费宝贵的人力时间。如果您无法在命令行上手动执行而不犯错误,请不要使用 bash/shell 编写脚本。
现在是 2015 年,因此我会考虑以下几点:
内存开销
- 与 bash 相比,Ruby/Python 运行时内存开销很小(因为有共享库),而且可能无法维护非平凡的 bash 脚本(即超过 100 行的脚本) - 因此内存使用量不是一个因素
启动时间
- Ruby/Python 的启动可能会稍微慢一点,但你很可能不会以每秒 100 次的速度在紧密循环中运行大量完整的 Ruby/Python 进程(如果你有这种需求,bash/shell 的开销太大了,你可能需要降到 C/C++)
表现
- 几乎所有典型的数据处理在 Ruby/Python 中都会更快 - 或者至少是相当的(或者,无论如何你需要 C/C++/Haskel/OCaml/whatever)
- 执行(甚至生产力)中的实际性能/瓶颈几乎永远不能是“缺乏使用 bash/shell”(即使 Ubuntu 切换 dash 作为启动项也表明 bash 实际上是问题所在 - 而 busybox 可能是唯一的用例,因为那里是只需使用“bash”和“vi”即可编写和运行代码,并且通常没有办法添加/下载或存储其他任何内容)
- 运行其他进程来完成这项工作(如 sed/awk/grep)实际上比调用内存中活动对象的方法要慢得多
生产率
- 与使用 Ruby/Python 中的“真实”方法、参数、变量和异常相比,在 Bash/shell 中犯错误太容易了
- Agile 是主流,而 Bash 并不支持它(缺乏单元测试功能、库、OO、模块化、linting、自省、日志记录、元编程;几乎不可能在不破坏某些东西的情况下进行重构)
- 与其他 shell 的不兼容性太多,微小的环境变量就可能完全破坏脚本(一些重要的开发操作工具,如 Puppet,会忽略 shebang 行并传递或重写重要的 shell 变量),而 Ruby/Python 即便是重大版本变更,也有明确定义的相对平滑的迁移路径
- 学习一门新语言只需要花费调试 shell 脚本时间的一小部分,因为 shell 脚本存在特定问题(特别是变量名、没有布尔值、没有异常等)
- 甚至启动脚本都是地雷(尤其因为它们可能会在系统您可能已经意识到,在启动时使用 Bash 可能会很困难(您可能已经意识到,在启动时使用 Bash 可能会很难),而且考虑到 Bash 最近存在的安全漏洞,您最好使用纯 C(带有良好的库)——是的,C 需要编译、配置等,但即使是一个简单的 shell 脚本也可能需要存储库,然后进行版本控制,然后进行打包。
- sed/awk/grep 中提供的任何功能很可能已经内置在 Ruby/Python 中 - 而不存在依赖关系,或者这些工具在不同平台上的版本之间没有“差异”(所以如果它可以在你的设置)
- 就业保障
- 获得一份你不喜欢的工作有什么意义?(除非你喜欢花费大量时间去调试很难但很容易产生的 shell 脚本错误)
我发现如果已经安装了 Ruby/Python 就没有必要使用 Bash/Shell。
并且可能安装 Ruby/Python 甚至根本不需要 bash 脚本(除了 busybox,一些系统工具依赖于 Python/Perl 的存在)。
每次你编写 shell 脚本时,你都在“练习”做同样的事情 - 而不是学习一些更强大/更有成效的东西。
为什么现在人们都使用 Bash?因为这是一个可怕的、难以戒除的习惯。脚本很少在最初几分钟后就“永远完成了”——无论人们多么强烈地这样认为。还有“这是这个脚本中的最后一个错误”的谬论。
结论:只有在绝对必要的情况下才使用 bash/shell强制(比如~/.bashrc
busybox),因为它几乎绝不如今,这是“完成工作所需的合适工具”。
答案3
当我主要关注文件处理时,我会使用 bash。这可能包括移动、复制和重命名文件,以及将文件用作其他程序的输入或将其他程序的输出存储在文件中。我很少编写实际检查文件内容或生成要写入文件的输出的 bash 代码;我将这些留给通过 bash 启动的其他程序(我可能用 Perl 或 python 编写)。
当我主要关注从文件读取数据、以某种方式处理数据以及将输出写入文件时,我会使用 Perl 和 Python。如果我发现自己过于频繁地使用(在 Perl 中)命令system
、后退标记或(在 Python 中)subprocess
模块,我会考虑用 Bash 编写脚本。另一方面,我有时会开始向 Bash 脚本添加太多功能,最终用 Perl/Python 重写它比处理 Bash 对变量范围、函数、数据结构等的有限(相比之下)支持更有意义。
答案4
我发现这个 Perl 与 Bash 的分析很有用...
http://blogs.perl.org/users/buddy_burden/2012/04/perl-vs-shell-scripts.html
为了方便起见,我复制了该作者的 1) 何时 bash 是更好的发现和 2) 何时 perl 是更好的结论的摘要......
当 Bash 变得更好时……
- 工作失败
- 退出时的命令
- 处理作业输出行
- 此处有文件
- 文件等价性
- 文件时间戳比较
- 波浪号扩展
当 Perl 更好时......
对于大多数应用程序来说,Perl 仍然比 bash 好很多。我更喜欢 Perl 的原因包括(但不限于):
- 它会更快。主要是因为我实际上不必为我想做的很多事情启动新进程(basename 和 dirname 是最明显的例子,但通常 cut、grep、sort 和 wc 也可以被消除)。
- bash 中的字符串处理充其量只是基本的,而整个 $IFS 东西非常笨重。
- Shell 脚本中的条件语句可能会不太稳定。
- 在 shell 脚本中引用可能是一个噩梦。
- bash 的 case 语句除了简单情况(NPI)之外还有很多不足之处。
- Bash 中的数组很烂。Bash 中的哈希(假设你的 Bash 足够新,可以有它们)更烂。
- 一旦处理文件或命令输出超出了我上面列出的简单情况,Perl 就会开始真正地抨击。
- 中央情报局。
因此,bash 不会在短期内取代 Perl。但经过这么多年,我仍然发现,很多时候简单的 shell 脚本有时比简单的 Perl 脚本更简单。正如我所说,我欢迎所有试图说服我的尝试。但话又说回来,在你的工具箱中拥有一些不同的工具并没有错。