kjo*_*kjo 8 bash zsh shell-script control-flow test
zsh 手册页在test(aka [)部分明确建议不要使用它,并敦促读者[[尽可能使用它。
在相关章节中指出:
该命令尝试在指定的位置实现 POSIX 及其扩展。不幸的是,语法中存在内在的歧义;特别是测试运算符和类似它们的字符串之间没有区别。该标准试图解决这些问题的少量参数(最多四个);不能依赖五个或更多参数的兼容性。敦促用户尽可能使用
[[没有这些歧义的“ ”测试语法。
我想我遇到过类似的 bash 建议,但是当我浏览 bash 手册页时,我找不到任何关于使用哪种表单([或[[)的“官方”建议。(也许我错过了?)
除了向后兼容“旧外壳”之外,还有什么理由可以
[在 bash 脚本中使用吗?或者换种方式,确实庆典保持[连同[[其原因其他比向后兼容?
不过也有一些细微的差别:
#!/bin/bash
eg=whatever
if [ $eg == what* ]; then # file glob test
echo '[]'
fi
if [[ $eg == what* ]]; then # pattern match test
echo "[[]]"
fi
Run Code Online (Sandbox Code Playgroud)
除非当前目录中有一个名为“whatever”的文件,否则第一个测试不会通过,因为匹配是针对当前目录内容的文件 glob,而第二个是实际的字符串模式匹配。
[优先选择[[if enough 的原因是它[在不同的 bash 版本之间更稳定。
看man bash:
兼容31
如果设置,bash 将其行为更改为 3.1 版关于 [[ 条件命令的 =~ 运算符的带引号参数的行为。
兼容32
如果设置,当使用 [[ 条件命令的 < 和 > 运算符时,bash 会将其行为更改为 3.2 版关于特定于区域设置的字符串比较的行为。bash-4.1 之前的 Bash 版本使用 ASCII 排序规则和 strcmp(3);bash-4.1 及更高版本使用当前语言环境的排序规则序列和 strcoll(3)。
兼容40
如果设置,则在使用 [[ 条件命令的 < 和 > 运算符(请参阅上一项)以及中断命令列表的效果时,bash 会将其行为更改为版本 4.0 的特定于区域设置的字符串比较。
也许对于有背景的用户来说也更常见一些ksh。
'[[' 比 '[' 更快
对于测量,您可以使用以下比较脚本
let upperBound=$1
echo "check [, ${upperBound} iterations"
let i=0
time while [ $i -lt ${upperBound} ] ; do let i++ ; done
echo; echo;
echo "check [[, ${upperBound} iterations"
let i=0
time while [[ $i < ${upperBound} ]] ; do let i++ ; done
Run Code Online (Sandbox Code Playgroud)
比较脚本的结果
检查 [,1000 次迭代
真实 0m0.031s
用户 0m0.028s
系统 0m0.004s检查 [[,1000 次迭代
真实 0m0.000s
用户 0m0.000s
系统 0m0.000s