我将坚持使用脚本功能。丰富的交互功能(命令行版本,完成,提示等)往往会大相径庭,以完全不兼容的方式实现相似的效果。zsh中有哪些功能,bash中缺少哪些功能,反之亦然?给出了一些交互式使用的指示。
最接近bash的是ATT ksh93或mksh(Korn Shell和克隆)。Zsh也具有功能的子集,但是您需要以ksh仿真模式而不是zsh纯模式运行它。
我不会列出POSIX功能(可在任何现代sh外壳程序中使用),相对晦涩的功能,也不会列出用于交互式使用的上述功能。从Debian wheezy上发现,bash 4.2,ksh 93u和mksh 40.9.20120630的观察结果有效。
$'…'(带有反斜杠插值的文字字符串)在ksh93和mksh中可用。$“…”(翻译后的字符串)特定于bash。
Mksh和ksh93必须;&在case声明中使用,但不能;;&测试后续案例。Mksh具有;|此功能,最近的mksh允许;;&兼容。
((…))算术表达式和[[ … ]]测试是ksh的功能。一些条件运算符有所不同,请参见下面的“条件表达式”。
Ksh和bash都有协同处理,但是它们的工作方式不同。
Mksh和ksh93除支持function name {…}标准外name () {…},还支持函数定义的语法,但function在ksh中使用时会更改作用域规则,因此name () …要保持兼容性。函数名称中允许使用的字符的规则各不相同;坚持字母数字和_。
Ksh93和mksh支持大括号扩展{foo,bar}。{1..42}Ksh93 支持数字范围,但mksh不支持。
ksh93的与mksh支持子提取${VAR:offset}和${VAR:offset:length},但不区分折叠状${VAR^},${VAR,}等等。你可以做大小写转换typeset -l,并typeset -u在两者的bash和ksh。
他们支持用${VAR/PATTERN/STRING}或替换${VAR/PATTERN//STRING}。STRING的引用规则略有不同,因此请在STRING中避免反斜杠(可能还有其他字符)(构建变量,${VAR/PATTERN/$REPLACEMENT}如果替换包含引号字符,则使用反斜杠)。
阵列扩展(${ARRAY[KEY]},"${ARRAY[@]}",${#ARRAY[@]},${!ARRAY[@]}在bash)工作像ksh的。
${!VAR}扩展到is ${OTHERVAR}的值(间接变量引用)特定于bash的情况(ksh与有所不同)。要在ksh中实现这种双重扩展,您需要使用名称引用()。工作原理相同。VAROTHERVAR${!VAR}typeset -n VAR=OTHERVAR; echo "$VAR"${!PREFIX*}
进程替换<(…),>(…)在ksh93中受支持,但在mksh中不受支持。
需要shopt -s extglob在bash中激活的ksh扩展glob模式始终在ksh93和mksh中可用。
Mksh不支持字符类[[:alpha:]]。
Bash和ksh93定义了伪文件和,但是mksh没有。/dev/tcp/HOST/PORT/dev/udp/HOST/PORT
在脚本重定向扩大通配符(如var="*.txt"; echo hello >$a写入a.txt,如果该文件名是该模式的唯一的比赛)是一个bash特有的功能(其它炮弹从来没有做到这一点的脚本)。
<<< 这里的字符串在ksh中的作用就像在bash中一样。
>&mksh也支持重定向语法错误的快捷方式,但ksh93不支持。
[[ … ]] 双括号语法
像bash一样,ATT ksh93和mksh都支持ksh的双括号语法。
文件运算符
Ksh93,mksh和bash支持POSIX的相同扩展名,包括,(粘性),(由egid拥有),(由euid拥有),(相同文件),(比新),(比旧)更旧的-a同义词。-e-k-G-O-ef-nt-ot
-N FILE (自上次读取以来已修改)不受mksh支持。
Mksh没有正则表达式匹配运算符=~。Ksh93具有此运算符,并且其执行与bash中相同的匹配,但BASH_REMATCH此后没有等效于检索匹配的组的操作。
字符串运算符
Ksh93和mksh支持相同的字符串比较运算符,<并且>作为bash以及的==同义词=。Mksh不使用语言环境设置来确定字典顺序,而是将字符串作为字节字符串进行比较。
其他运营商
-v VAR测试是否定义了变量是bash特定的。在任何POSIX Shell中,您都可以使用[ -z "${VAR+1}" ]。
别名中允许的字符集在所有shell中都不相同。我认为这与功能相同(请参见上文)。
Ksh93具有一个名为的内置builtin函数,但它不会将名称作为内置命令来执行。使用command旁路别名和功能; 如果存在,则会调用一个内置命令,否则将调用一个外部命令(可以使用来避免这种情况PATH= command error_out_if_this_is_not_a_builtin)。
这是特定于bash的。你可以得到一个类似的效果.sh.fun,.sh.file并.sh.lineno在ksh93的。在mksh中,最后有一个LINENO。
declare是ksh的bash专用名称typeset。使用typeset:它也可以在bash中使用。
Mksh定义local为的别名typeset。在ksh93中,您需要使用typeset(或定义一个别名)。
Mksh没有关联数组(它们计划用于尚未发布的版本)。
我不认为typeset -tksh中有bash的(跟踪函数)的完全等效项。
Ksh93没有-e。
Ksh93和mksh处理bash 中的-e和-n选项。Mksh也了解-E,ksh93不会将其视为选项。在ksh93中,默认情况下,反斜杠扩展处于关闭状态;在mksh中,默认情况下处于启用状态。
Ksh没有提供禁用内置命令的方法。为避免内置,请查找外部命令的路径并显式调用它。
Ksh93有-a但没有-l。Mksh都没有。
ksh93和mksh都没有export -n。typeset +x foo改为使用,它可以在bash和ksh中使用。
Ksh不会通过环境导出功能。
let 在bash和ksh中是相同的。
这是bash特有的功能。您可以使用while read循环或命令替换来读取文件并将其拆分为行数组。保重IFS并保持平衡。这相当于mapfile -t lines </path/to/file:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf非常相似。我认为ksh93支持bash的所有格式指令。mksh不支持%q或%(DATE_FORMAT)T; 在某些安装中,printf它不是内置的mksh,而是调用外部命令。
printf -v VAR 是特定于bash的,ksh始终打印到标准输出。
有几个bash特定的选项,包括有关readline的所有选项。选项-r,-d,-n,-N,-t,-u是在bash,ksh93的和mksh相同。
您可以使用相同的语法在Ksh93和mksh中将变量声明为只读。如果变量是数组,则需要首先分配给它,然后使用将其设为只读readonly VAR。在ksh中不能将函数设为只读。
所有的选项set,并set -o为POSIX或ksh功能。
shopt是特定于bash的。无论如何,许多选项都涉及交互式使用。有关某些选项启用的对滚动和其他功能的影响,请参阅下面的“选项”部分。
的这种变体也.存在于ksh中。在bash和mksh中,source在之后搜索当前目录PATH,但是在ksh93中,它与完全等效.。
该DEBUG伪信号不mksh实现。在ksh93中,它以不同的方式报告信息,有关详细信息,请参见手册。
在ksh中,type是的别名whence -v。在mksh中,type -p不打印可执行文件的路径,而是打印一条人类可读的消息。您需要使用whence -p COMMAND。
选件
要模拟dotglobksh93中的选项,可以设置FIGNORE='@(.|..)'。我认为mksh中没有这样的东西。
该extglob选项实际上始终在ksh中启用。
我认为这在mksh或ksh93中都不存在。它在zsh中(默认行为,除非null_glob或csh_null_glob设置)。
Ksh93具有递归glob **/,已启用set -G。Mksh没有递归glob。
Ksh93始终在父外壳程序中运行管道的最后一个命令,在bash中,这需要设置lastpipe选项。Mksh始终在子Shell中运行管道的最后一个命令。
Mksh没有不区分大小写的模式匹配。Ksh93逐个模式支持它:在模式前面加上~(i)。
Mksh没有这个。Ksh93逐个模式支持它:在模式前面加上~(N)。
显然,大多数BASH_xxx变量都不存在于ksh中。$BASHPID可以用昂贵但可移植的来模拟sh -c 'echo $PPID',并且最近已添加到mksh中。BASH_LINE是.sh.lineno在ksh93的和LINENO在mksh。BASH_SUBSHELL是.sh.subshell在ksh93的。
Mksh和ksh93都在ENV启动时提供给定的文件。
EUID并且UID在ksh93中不存在。Mksh称他们USER_ID和KSH_UID; 它没有GROUPS。
FUNCNAME并且FUNCNEST在ksh中不存在。Ksh93具有.sh.fun和.sh.level。用function foo { …; }(没有括号!)声明的函数在中具有自己的名称$0。
GLOBIGNORE在ksh93中存在,但具有不同的名称和语法:称为FIGNORE,它是单个模式,而不是用冒号分隔的列表。使用@(…|…)模式。Ksh FIGNORE包含bash的语法完全不同。
Ksh93和mksh没有类似的东西HOSTTYPE,MACHTYPE并且OSTYPE。也SHELLOPTS还是TIMEFORMAT。
Mksh有PIPESTATUS,但ksh93没有。
Mksh和ksh93具有RANDOM。