Shell脚本与Python相比的优势

114

我曾几次尝试学习shell(bash)脚本,但是语法驱使我离开。后来我发现了Python,并能够用Python完成大部分shell脚本能做的事情。现在我不确定是否应该再投入时间学习shell脚本。因此,我想问:

与Python相比,shell脚本有哪些优势,使它成为一种不可或缺的工具?

我不是专业的系统管理员,但我对为家庭用户设置Linux系统感兴趣,因此我认为学习shell脚本可能会变得必要。


2
除了Python之外,还有其他选择。Kotlin支持脚本编写,可以作为Python的良好替代品,因为它既简洁(像Python一样),又类型安全。与Python一样,请确保在您的计算机上安装了Kotlin编译器。在此处查看Kotlin hello world脚本以及带有库依赖项的真实世界脚本。此外,Kotlin现在已经可用于GitHub Actions环境 - Mahozad
8个回答

96
  • Shell脚本对于I/O重定向使用更简单的符号。
  • 在shell中,将现有程序组合成管道更为简单。
  • Shell脚本可以重复使用整个程序。
  • Shell是通用的(在任何类Unix系统上都可用),而Python未必已安装。

虽然Python能做到shell所能做的一切,但事实也是,在Python中有些东西很容易,而在shell中很难(就像在Python中有些东西很难,而在shell中很容易)。长远来看,了解两者会更好。


22
1和2,是优点。#3是弱点,因为它导致了很多开销,而Python可以避免这种情况。#4可能大部分是不真实的。现在Python已经成为大多数Linux发行版的一部分。 - S.Lott
2
我认为第三点不是缺点,而是巨大的优势。例如,考虑使用convert程序调整大小充满图像的目录。 - Glenn
7
关于第四点需要注意的是,在嵌入式系统和运行busybox可执行文件的某些Linux发行版中,特别是bash shell并不普遍可用。针对Bourne shell本身的脚本,它们与bash向后兼容,将在所有符合POSIX标准的系统上运行,但该语言比bash实现的语言要受到更多限制。 - intuited
5
@intuited: eval "$(history 2 | head -1 | perl -pe 's/(?<=which is )more probably/at least/')"; history -d $(history 2 | head -1 | sed 's/^\s*([0-9]+)/\1/')请注意,该命令是一条Linux终端命令,用于删除历史记录中的特定条目。如果你想使用这个命令,请确保你知道它的作用以及如何正确地使用它。以下是翻译内容: @intuited: eval "$(history 2 | head -1 | perl -pe 's/(?<=which is )more probably/at least/')"; history -d $(history 2 | head -1 | sed 's/^\s*([0-9]+)/\1/')这条命令会删除你在Linux终端历史记录中指定的条目。不要忘记在使用前了解该命令的作用并正确使用。 - intuited
1
业主能否更新一些关于在Shell中容易但在Python中较难的例子以及在Python中容易但在Shell中较难的例子? - Junchen Liu
显示剩余6条评论

61
"相较于Python,shell脚本具有哪些优势使其成为不可或缺的工具?"

Shell并不是不可或缺的工具。你认为为什么会有这么多种类型的Shell呢? 比如bash、tcsh、csh、sh等等。

Python本身就是一个Shell。虽然它不适合用来运行所有命令,但对于脚本编写来说,它是理想的选择。

Python已经成为几乎所有Linux发行版中标配的一部分。

更传统的shell做了太多的事情。

  1. 它们有一个方便的用户界面来运行命令。这包括一些一行命令,其中shell搜索您的PATH,然后fork和执行所请求的程序。它还包括管道、序列和并发程序(使用;|&),以及一些重定向(使用><)。

  2. 他们有一个类似于编程语言的能力来运行脚本。这种语言很难使用,而且非常低效。在这种语言中,大多数语句需要派生出一个或多个额外的进程,浪费时间和内存。

从shell中运行程序、将stderr重定向到日志文件等操作是不错的。可以在shell中执行这些操作。

几乎所有其他任务都可以用Python脚本更高效、更清晰地完成。

你需要二者兼备。但是,在传统的shell语言中,永远不要编写带有if语句或循环的脚本。


4
似乎这里的电路存在一些语义上的不协调。我的定义是UNIX shell是一种解释器,其语言主要面向在高层次上控制UNIX系统操作。按照这个定义,某种类型的shell对于UNIX系统的运作至关重要,而Python则不符合要求。你会如何定义这个术语? - intuited
1
@S.Lott:我不是传统 shell 脚本中使用的语法的忠实粉丝,但我发现它相当可用,在许多需要控制进程及其输出流的情况下是适用的。这通常需要做出决策和迭代。现代 shell(至少包括bash)具有内置的决策处理功能(例如,testbash 的内置命令,除了更灵活的构造)。它肯定有其弱点,但也有其优点。值得详细学习,因为它与其他类型的编程语言完全不同。 - intuited
1
@intuited: "shell" 的意思是它能正确响应 #! 协议。它可以被严格解释,或者被编译成字节码并解释,或者(像 awk 一样)被编译成二进制文件并执行。要成为一个 shell,应用程序必须接受以 #! 开头的可执行文件,并正确地处理它。 - S.Lott
1
@S.Lott:我会将其作为UNIX“脚本语言”的定义,而不是“shell”的定义。实际上,我开始更多地使用Python作为系统shell;您能推荐一些有用的软件包来提供管道功能吗? - intuited
3
@S.Lott:有趣,你的哲学和我大不相同。我认为设计与操作基本上是鸡与蛋的关系。也就是说,一个shell脚本是运行程序的程序。其中许多程序最初都是用越来越复杂的shell脚本实现的。在某个时刻,出于效率和模块化的考虑,有必要将其中一些重写为C语言或Python,这样做可能更值得。例如:在某个时候 cat "$1" | ssh "$2" "cat - >\"$1\"" 衍生出了 scp。他们知道如何最好地设计它,因为他们已经在使用它了。 - intuited
显示剩余11条评论

39

Shell可以使常见和简单的操作变得非常简单,但代价是将更复杂的事情变得更加复杂。

通常情况下,一个小的shell脚本会比相应的python程序更短、更简单,但python程序往往会优雅地接受修改,而shell脚本随着代码的添加会越来越难以维护。

这意味着为了实现每日最佳生产力,您需要使用shell脚本,但大多数情况下应该将其用于一次性的脚本,并在其他方面使用python。


17

使用Python可以完成Shell脚本所能做的一切。Shell脚本的优势在于使用与Shell相同的命令,因此如果您是Shell用户,则编写Shell脚本最终将成为自动化Shell工作的一种快速简便方法。

对我而言,在Shell脚本中处理数据管道比在Python中更容易,虽然在Python中也完全可行。

最后,您不必启动额外的解释器来运行Shell脚本,这会带来非常小但有时或许会被注意到的速度和内存使用优势。

但另一方面,Python脚本更易于维护。出于这个原因,我正在尝试从丑陋的大型Shell脚本迁移到Python脚本。使用Python还更容易进行异常处理和质量保证。


11

并不是非要学习Shell脚本,正如之前的回答所指出的那样;但学习从来都不是坏事。这实际上是一个个人优先事项的问题。别人很难告诉你什么值得、什么不值得你花时间去做。

大多数程序员发现,每次学习新语言都会变得更加容易(自然语言也是如此)。而且你越早开始,越好。

此外:学习一门语言使你能够从完全了解和熟悉的位置挥霍其限制。这可能不会让你约会成功,但可能会赢得同行的赞赏!


9

我赞同大部分之前的回答。在我看来,shell命令最适合执行基于文件系统的任务(复制和移动文件、grep等)。如果您需要读写文件,那么在我的意见中,shell更好,因为单个>>file.txt重定向会立即将内容追加到文件中,而不需要像file=open('file.txt','a'); file.write()那样进行操作。

目前,对于我的个人使用,我混合着两种方式,创建一个Python脚本,并在一些操作更容易在shell中执行时调用os.system('command')或os.popen('command')。


7

Shell是一种无处不在的工具。如果你使用相对基本的可移植功能,你的脚本可以运行在手机、无线路由器、DVR、上网本、工作站、大型服务器等各种设备上。Python并不是所有系统都默认安装的,而且根据环境的不同,安装它可能会很困难。

学习一些Shell脚本编程也可以帮助你学习一些命令行技巧,因为命令行就是Shell。此外,当你意识到需要经常使用某个较长或较复杂的命令时,将其转换为更通用的脚本也是非常好的。

Shell还有一些非常强大的功能;管道是一种非常有趣的控制结构,据我所知它只在Shell中原生支持。


5

在选择Python的shell脚本时,需要考虑将在目标机器上运行的Python版本。比如RHEL5,它将长期存在,但被固定在Python 2.4上。有很多不错的库依赖于Python 2.4之后的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接