Answers:
鉴于两者都可以解决的问题,您将需要使用最适应的问题。最终,有很多小细节,只有经验可以教您看它们。
Bash是通用的脚本语言,就像Python,Ruby,Perl一样,但是每种语言在其他方面都有不同的优势。Perl擅长进行文本分析,Python声称是同类中最优雅的,Bash脚本非常擅长“四处传播”,如果您知道我的意思的话,那么Ruby ...好吧,Ruby在很多方面都与众不同的方式。
但是,只有当您拥有足够的脚本编写经验后,它们之间的差异才真正重要。我建议您选择一种语言并将其推到极限,然后再使用另一种语言。在shell脚本中,您可以做很多事情,这比大多数人所承认的要多。任何一种语言都像您想做的一样难。在其中编写了几本书之后,每种语言对您来说都是“轻松”的。
如果您生活在Linux中,那么对Shell的熟悉会很快获得回报,因此也许您想从此开始。如果您发现在Shell脚本中无法解决或不切实际的任务,请使用其他方法。
另外,请记住,学习shell脚本非常简单。它的真正功能在于其他程序,例如awk,sed,tr等。
是2015年,所以我考虑以下几点:
内存开销
启动时间
性能
生产率
如果您安装了Ruby / Python,我发现没有理由使用Bash / Shell。
也许首先安装Ruby / Python甚至不需要bash脚本(除了busybox之外,某些系统工具仍然依赖于Python / Perl)。
每次编写shell脚本时,您都是在“练习”做完这些事情-而不是学习更强大/更有成效的东西。
为什么人们如今使用Bash?因为这是一个可怕的,难以打破的习惯。最初几分钟后,脚本很少“永远完成”-不管人们倾向于以这种方式思考。还有“这是该脚本中的最后一个错误”谬论。
结论:仅当您绝对被迫使用bash / shell时(例如~/.bashrc
busybox),因为当今它几乎从来都不是 “正确的工作工具”。
我主要关注文件处理时使用bash。这可能包括移动,复制和重命名文件,以及将文件用作其他程序的输入或将其他程序的输出存储在文件中。我很少编写bash代码来实际检查文件的内容或生成输出以写入文件;我将其留给我通过bash启动的其他程序(可以用Perl或python编写)。
当我主要关注从文件中读取数据,以某种方式处理该数据并将输出写入文件时,我使用Perl和python。如果我发现自己(在Perl中)使用了system
命令,反勾或在python中使用了subprocess
太多模块,则考虑使用bash编写脚本。另一方面,我有时会开始向bash脚本添加太多功能,最终使它更有意义地是用Perl / python重写它,而不是处理bash对变量作用域,函数,数据结构等的有限(通过比较)支持。
=~
操作员的支持后,[[ ]]
我一直爱我一些用于简单文件读取的Bash
我发现此Perl vs Bash分析很有用...
http://blogs.perl.org/users/buddy_burden/2012/04/perl-vs-shell-scripts.html
为了方便起见,我复制该作者的摘要:1)bash是更好的发现,2)perl是更好的结论...
当Bash更好时...
- 工作失败
- 退出命令
- 处理作业输出线
- 这里文件
- 文件等效
- 文件时间戳比较
- 波浪扩展
当Perl更好时...
对于大多数应用程序,Perl仍然不胜其烦。我可能更喜欢Perl的原因包括(但不限于):
- 它会更快。主要是因为我实际上不需要为许多我想做的事情启动新进程(最明显的例子是基名和目录名,但通常也可以删除cut,grep,sort和wc)。
- bash中的字符串处理充其量是最基本的,整个$ IFS东西非常笨重。
- Shell脚本中的条件语句可能很奇怪。
- 引用shell脚本可能是一场噩梦。
- 除了简单案例(NPI)之外,bash的case语句还有很多需要改进的地方。
- bash中的数组很烂。bash中的哈希(假设您的bash足够新,可以完全使用它们)更难吸。
- 一旦处理文件或命令输出超出了我上面列出的简单情况,Perl就开始真正冒烟。
- CPAN。
因此,bash不会很快就取代Perl。但是,这些年来,我仍然发现,有时候简单的shell脚本有时会比简单的Perl脚本简单。正如我所说,我欢迎所有试图说服我的尝试。但是,话又说回来,在您的工具箱中拥有一些不同的工具并没有错。
fail "error" unless system("foobar")
)。
Bash是Unix shell,它包含脚本语言。它是命令处理器。您可以控制运行命令的方式,也可以实际运行它们。
Perl / Ruby / Python是通用语言。
当您需要shell脚本时,可以使用Bash
如果您想要更复杂的任务或与外壳无关。使用Python等
我绝对不会比较这些语言。Python等是可移植的。您可以在任何地方运行它们。Bash仅适用于Unix。
Python等具有大量可重用的库,可解决数百万个任务。
如果您问的话,几乎是一样的。“何时使用Paint和何时使用Photoshop”
对于电子邮件处理,我将再次使用Ruby,因为它具有许多可重用的库。
但是最好的方法是结合bash和ruby。没错。就像您在ruby中创建电子邮件处理脚本一样,bash脚本将调用该ruby脚本并运行其他命令ds。
因此,无论何时需要命令处理器,都可以使用bash。您运行unix命令并对其进行控制。
尽管答案的主要部分没有变化,但我想指出这一点。
Bash也是一种功能强大的脚本语言。对于文本处理,这可能是绝对合法的选择。
请在下面阅读mkaito的评论。它们都是完全正确的。
高度偏见的文章。
我发现bash很难调试。Python通常过于僵化,而bash可以让您变得很有创造力。如果您是一个出色的开箱即用的思想家,那么您会喜欢bash。
我对成千上万个文件中的数百万个DNA测序读取数据运行bash脚本,这对我很有帮助。与每个人都说的相反,C ++中相同版本的脚本实际上并没有那么快地运行(在几分钟内将它们分开)。
我认为bash像perl一样,不是最用户友好/最容易阅读的。这吓跑了人们,因为大多数人都不是伟大的抽象思想家。但是更聪明,更有创造力的程序员往往喜欢它并经常使用它。如果您了解自己并且知道自己有大脑,请不要被bash吓到。如果您是一个基本的思想家,则可以坚持使用Python之类的工具。给每个人自己。
摘自《骆驼书》
Perl试图填补低级编程(例如C或C ++或汇编语言)和高级编程(例如“ shell”编程[例如
bash
])之间的空白。低级编程通常很难编写和丑陋,但快速且不受限制。在给定的机器上,很难击败编写良好的低级程序的速度。而且那里没有太多你不能做的。另一方面,高级编程往往很慢,很困难,很丑陋而且很有限。如果您的系统上没有提供所需功能的命令,那么在Shell或批处理编程中您根本无法做很多事情。Perl很容易,几乎是无限的,大多是快速的,并且有点丑陋。
作为经验法则,请使用性能足以胜任您手头任务的最简单的语言。而且它的特殊性仅在扩展时才真正有用。
关于可读性,如果您的编程风格很糟糕,那么Bash将会很糟糕。如果您只是在那上面扔代码,它就会变得晦涩难懂。
但是,如果将代码拆分为最短的函数,并以一种简单易懂的方式命名事物,那么它就是您可以找到的最清晰的语言。因为它非常简洁。
作为标本,这是我在Bash中最新的代码。注意它的易于理解和输入方式:
#! /bin/bash
mainFunction () {
file="${1}"
checkFile "${file}"
executeFile "${file}"
}
changeToThisProgramDir () {
cd "$( dirname "${BASH_SOURCE[0]}" )"
}
checkFile () {
file="${1}"
checkFileNotEmpty "${file}"
checkFileExist "${file}"
checkFileIsExe "${file}"
}
checkFileExist () {
file="${1}"
if [ ! -f "${file}" ]; then
echo "The file doesn't exist: ${file}" >&2
echo "If the name was correct either type: exeCute \"pathToYourExeFile\""
echo "Or just open with exeCute from the file manager"
exit 1
fi
}
checkFileIsExe () {
file="${1}"
mime=$(fileMime "${file}")
if [ "${mime}" != "application/x-dosexec" ]; then
echo "Not an exe: ${file}" >&2
exit 1
fi
}
checkFileNotEmpty () {
file="${1}"
if [ "${file}" == "" ]; then
echo "No file specified" >&2
echo "Either type this: exeCute \"pathToYourExeFile\""
echo "Or just open with exeCute from the file manager"
exit 1
fi
}
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: ${error}" >&2
exit 1
fi
}
executeFile () {
file="${1}"
type=$(fileType "${file}")
if [ "${type}" == "MS-DOS executable" ]; then
execute "executeFile" "dosbox \"${file}\" -forcescaler normal2x -exit -fullscreen"
else
execute "executeFile" "wine \"${file}\""
fi
}
fileMime () {
file="${1}"
attributes=$(file --brief --mime "${file}")
IFS=";" read -r -a attributes <<< "${attributes}"
echo "${attributes[0]}"
}
fileType () {
file="${1}"
attributes=$(file --brief "${file}")
IFS="," read -r -a attributes <<< "${attributes}"
echo "${attributes[0]}"
}
changeToThisProgramDir
mainFunction "${@}"