Answers:
对于初学者,如果您可以假设已预先安装Bash(据我所知,您列出的所有系统都是这种情况),请使用以下hashbang进行兼容:
#!/usr/bin/env bash
这会调用任何bash
碰巧要配置的内容,无论它位于/bin
还是/usr/local/bin
。
在范围广泛的大多数系统(包括AIX,Solaris和几种BSD版本)上,它们bash
最终都位于不同的位置,而env
最终总是最终出现在/usr/bin/env
。但是,诀窍不是我的,而是Bash Cookbook的作者。
无论如何,是的,Bash允许您使用一些“现代”功能,使您的生活更轻松。
例如,双括号:
[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"
而在传统的壳方言中,您必须求助于:
test -f "/etc/debian_version" && echo "This is a Debian flavor"
但是关于双括号的最好之处在于它们允许使用正则表达式进行匹配。该猛砸黑客维基会给你很多的技巧在那个方向。
您也可以使用非常方便的表达式,例如$((2**10))
或与$((expression))
语法内联的其他算术表达式。
对子壳使用反引号也可以,尽管有些过时了。但是,$(command ...)
调用的嵌套功能更加方便,因为您不必在不同的子Shell级别上转义许多事情。
这些只是Bash在传统的常见POSIX sh
语法上为您提供的一些内容。
但是,如果您想在shell上拥有更多功能(不仅仅是在脚本中),还可以看看zsh
。
sh
执行此类任务。
sh
链接到的系统上bash
,不能通过使用缓解漏洞sh
。
在Debian和Ubuntu中,/bin/sh
是dash
,它是POSIX兼容的外壳。如果指定#!/bin/sh
,则必须在脚本中将自己限制为POSIX语句。(优点是dash
启动速度比快bash
,因此您的脚本可以在更短的时间内完成工作。)
在许多(大多数?)其他Linux系统上,/bin/sh
是bash
,这就是为什么#!/bin/sh
即使使用bash
扩展名也将许多脚本写为shebang行的原因。
如果要使用bash
扩展名,则在所有系统上最安全的方法是指定#!/bin/bash
; 这样,您就明确声明了对的依赖bash
。您需要在Debian和Ubuntu上执行此操作。作为一个额外的好处,当作为开始/bin/sh
bash
去激活一些扩展(见的描述bash
POSIX模式的详细信息); 因此#!/bin/bash
必须进行指定才能充分利用bash
。
在OS X上/bin/bash
也可用,并且/bin/sh
为bash
。指定#!/bin/bash
在那里也可以正常工作。
是的,OSX和Linux都将随附/bin/bash
。您应该绝对安全。但是,那不是 POSIX。POSIX Shell /bin/sh
最多(所有)系统上,这是最可移植的方法,也是唯一兼容POSIX的方法。
请注意,尽管在许多系统上/bin/sh
指向bash
,在其他系统上却可以指向不同的外壳。例如,这是dash
在Debian和Ubuntu上的符号链接。同样,即使/bin/sh
是的链接bash
,当它被称为sh
(来自man bash
,强调我的)时,shell的行为也会改变:
如果使用名称sh调用bash,则它会尝试尽可能接近于sh的历史版本的启动行为,同时也要符合POSIX标准。 当作为交互式登录外壳程序或带--login选项的非交互式外壳程序调用时,它首先尝试按该顺序从/ etc / profile和〜/ .profile中读取和执行命令。--noprofile选项可用于禁止此行为。当以名称为sh的交互式shell调用时,bash查找变量ENV,如果为
定义,并将扩展值用作要读取和执行的文件的名称。由于以sh调用的shell不会尝试从任何其他启动文件读取和执行命令,因此--rcfile选项无效。 使用名称sh调用的非交互式外壳程序不会尝试读取任何其他启动文件。当作为sh调用时,bash在读取启动文件后进入posix模式。
如果绝对要与“所有Unix系统”兼容- 如果不是,那么为什么要编写Shell脚本?-那么,是的,您应该使用#! /bin/sh
,因为不能保证Bash可以安装在任何地方,更不用说在了/bin
。
实际上比这差得多。如果您需要与所有 Unix系统兼容,那么其中包括Solaris和AIX之类的东西会冻结其大约在1995年的外壳环境。这意味着您必须使用诸如老式sort +N
语法之类的东西- 新系统已经废弃!而且这也意味着没有外壳函数,没有数组,没有[[ ... ]]
,没有${foo#glob}
,没有$(( ... ))
用于算术,可能没有$( ... )
样式的命令替换,对输入量有多大的小且未记录的上限...
您也许可以不用担心那么多的兼容性,但是如果一开始它甚至是个问题,我强烈建议您考虑使用一种不如Shell糟糕的语言。基本的Perl解释器比Bash 更可能可用。
/bin
和合并/usr/bin
。结果,如今最好使用#!/usr/bin/env <shname>
可移植性。