我刚刚完成第二年的大学CS学习,所以我缺乏对“现实世界”的了解。我第一年学习Java,然后继续学习Java,第二年学习了C和简单的Bash脚本。今年夏天,我正在尝试学习Perl(上帝帮助我)。我过去有点涉猎Python。
我的问题是,既然我们拥有易读,可写的脚本语言,例如Python,Ruby,Perl等,为什么有人编写Bash脚本?有什么我想念的吗?我知道我的linux机器有perl和python。它们不够普及吗?在Bash中确实有比在其他hll中更容易做的事情吗?
我刚刚完成第二年的大学CS学习,所以我缺乏对“现实世界”的了解。我第一年学习Java,然后继续学习Java,第二年学习了C和简单的Bash脚本。今年夏天,我正在尝试学习Perl(上帝帮助我)。我过去有点涉猎Python。
我的问题是,既然我们拥有易读,可写的脚本语言,例如Python,Ruby,Perl等,为什么有人编写Bash脚本?有什么我想念的吗?我知道我的linux机器有perl和python。它们不够普及吗?在Bash中确实有比在其他hll中更容易做的事情吗?
Answers:
除其他事项外,当您正在执行的大部分工作是在各种程序之间进行通信和管道传输(其中许多也是标准程序)时,bash很有用。在许多环境中,bash(或至少是POSIX shell)可用,而Perl和Python没有。
当然,您应该区分交互式bash和脚本化bash。Ubuntu最近将默认的脚本化shell(#!/bin/sh
)改为dash,因为它的速度要快得多。但是,bash具有有用的交互功能,而dash没有(zsh更好,恕我直言)。
Bash脚本允许您使用与手动键入命令相同的语言来自动执行命令行任务。
#!/bin/sh
echo $PATH
import os
print os.getenv("path")
我认为,对于许多任务而言,python不如bash那样自然是一个很强的论点,这是一个简单的事实,没有人将python解释器用作其shell。显然这是可能的:
python> import os, subprocess
python> os.chdir(os.path.expanduser("~/work"))
python> subprocess.call(["vim","README"])
显然,使用python作为外壳是荒谬的。Bash设计用于运行其他程序。Python专为进行计算而设计。虽然大多数事情都可以用任何一种语言完成,但总有一些任务可以比使用python更容易在bash中完成,反之亦然。
os.path.expanduser
电话。完整的pythonic版本会更糟:os.path.join(os.path.expanduser("~"),"dev")
。而且,即使您真的想从python中运行vim,也不要考虑IO重定向将如何工作。我认为我的观点很明确。
传统上,许多启动脚本都是作为Shell脚本编写的,似乎没有任何趋势可以摆脱它们。
Shell脚本非常适合启动其他进程并将其输入/输出粘合在一起。这是其他脚本语言不那么强大的领域。
除此之外:即使像Perl,Python和Ruby之类的语言变得越来越普遍,在每个类unix的系统上实际上可以保证的唯一语言是bourne shell(尽管不一定采用bash的形式)。
Bash不仅是一种脚本语言,而且是一种外壳程序。
作业控制语言和Shell
主要文章:Shell脚本作业控制的自动化已发展出一大类脚本语言,这涉及启动和控制系统程序的行为。(从这个意义上讲,人们可能会把shell看作是IBM JCL或Job Control Language的后代,正是这种语言正是出于此目的而使用的。)这些语言的许多解释器兼用作命令行解释器,例如Unix shell或MS-DOS COMMAND.COM。其他脚本(例如AppleScript)提供了类似英语的命令来构建脚本。结合Mac OS X的Cocoa框架,用户可以使用AppleScript&Cocoa对象构建整个应用程序。
Python,Ruby和Perl很棒,但是更通用。在某些情况下(嵌入式设备或其他简约系统),它们可能会显得过大,或者在其他情况下,它们可能会带来安全风险(对于您想要非常高的安全性并尝试消除任何不必要的程序包的环境)。
在某些情况下,由于与OS的紧密集成,shell脚本的性能会更好。
而且,bash已通过生产验证,可用于多种管理任务,并且很容易找到可以覆盖非常复杂的场景(异常)并优雅地处理它们的脚本。
我是一个perl专家,但是我每天使用和创建的bash(或ksh)函数的数量非常重要。对于涉及的所有内容,我将编写一个perl脚本,但是对于导航目录结构,以及专门用于处理环境变量bash / ksh / ...来说,必不可少。
同样,特别是对于环境变量,没有什么比外壳程序更胜一筹了,并且很多程序都使用环境变量。在Perl中,我必须编写一个bash别名或函数来调用Perl脚本,该脚本会写出一个临时bash脚本,然后在Perl退出后获取该bash脚本以在与我启动时相同的环境中进行更改。
我已经做到了,尤其是对于繁琐的路径变量。但是没有办法仅在Perl(或python或ruby ...或C代码)中做到这一点。
您可能会在新鲜肉上获得真正的出价(例如,在Mac OS X上,/ bin / sh不是真正的出价)。
如何识别传统的伯恩贝壳?...对一个经常未记录但具有特征的特征进行简单检查:您可以使用circumflex ^(插入符号)代替|。(管)。
以我的经验,Perl满足了可能需要Shell脚本的99%的需求。另外,可以编写在Windows上不运行Cygwin的代码。如果我要定位的Windows框上没有安装Perl,则可以使用PAR :: Packer或PerlApp生成可执行文件。Python,Ruby和其他工具也应同样工作。
但是,shell脚本并不那么复杂-至少您应该在shell中编写脚本的事情并不那么复杂。您可以用相当浅的知识来完成所需的工作。
了解如何读取和设置变量。如何创建和调用函数。如何获取其他文件。了解流量控制的工作原理。
最重要的是,学习阅读Shell手册页。这听起来可能很有趣,但是我100%认真-不用担心将Shell脚本的每个细节塞入大脑,而是学会快速,有效地在手册页中找到需要了解的内容。如果您发现自己经常使用Shell脚本,则相关信息自然会留在您的大脑中。
因此,是的,基本外壳程序值得学习。
我不明白的是为什么人们bash
在说任何bourne-shell
兼容的外壳时都会说。
编写shell脚本时:始终尝试使用在较旧的bourne shell解释器中也可以使用的构造。有一天,它将为您节省很多麻烦。
是的,如今,shell脚本有很多用途,因为外壳始终存在于所有unix上,与perl,python,csh,zsh,ksh(可能是?)相反,开箱即用。在大多数情况下,它们只会为循环和测试之类的结构添加额外的便利或不同的语法。有些具有改进的重定向功能。
在大多数情况下,我会说普通的bourne shell同样有效。
典型的陷阱:
if ! test $x -eq $y
在具有更聪明的内置“ if”运算符的bash中按预期方式工作,但“正确”if test ! $x -eq $y
应在所有环境中均有效。