Difference between single and double square brackets in Bash
我正在阅读有关
1 2 3 4 | if [ -f $param ] then #... fi |
其他双方括号:
1 2 3 4 | if [[ $? -ne 0 ]] then start looking for errors in yourlog fi |
有什么区别?
单个
双
只要您希望脚本可以跨shell进行移植,就可以使用
行为差异好的。
在bash 4.3.11中测试:好的。
posix与bash扩展:好的。
[ 是posix[[ 是一个bash扩展1,文档如下:https://www.gnu.org/software/bash/manual/bash.html conditional constructions
常规命令vs魔法好的。
[ 只是一个有着奇怪名字的常规命令。好的。] 只是[ 的一个论点,它阻止了进一步的论点的使用。好的。Ubuntu16.04实际上在coreutils提供的
/usr/bin/[ 上有一个可执行文件,但是bash内置版本优先。好的。bash解析命令的方式没有任何改变。好的。
具体来说,
< 是重定向,&& 和|| 连接多个命令,( ) 生成子代码,除非由\ 转义,并且字扩展照常发生。好的。[[ X ]] 是一个使X 能够被神奇地解析的单一构造。对< 、&& 、|| 和() 进行了特殊处理,分词规则不同。好的。还有其他的区别,如
= 和=~ 。好的。在bashese中:
[ 是内置命令,[[ 是关键字:https://askubuntu.com/questions/445749/whats-the-difference-between-shell-built in-and-shell-keyword好的。
< 好的。[[ a < b ]] :辞书编纂比较[ a \< b ] :同上。\ 是必需的,或者像其他命令一样进行重定向。BASH扩展。expr a \< b > /dev/null :posix equivalent2,参见:如何在bash中测试词法小于或等于的字符串?
&& 和|| 。好的。[[ a = a && b = b ]] :真、逻辑和[ a = a && b = b ] :语法错误,&& 被解析为与命令分隔符cmd1 && cmd2 。[ a = a -a b = b ] :等效,但被posix3否决[ a = a ] && [ b = b ] :posix和可靠的等价物
( 好的。[[ (a = a || a = b) && a = b ]] :假[ ( a = a ) ] :语法错误,() 被解释为子shell[ \( a = a -o a = b \) -a a = b ] 相当,但posix不赞成() 。{ [ a = a ] || [ a = b ]; } && [ a = b ] posix等价物5
扩展后的分词和文件名生成(split+glob)好的。
x='a b'; [[ $x = 'a b' ]] 对,不需要报价x='a b'; [ $x = 'a b' ] :语法错误,扩展到[ a b = 'a b' ] 。x='*'; [ $x = 'a b' ] :当前目录中有多个文件时出现语法错误。x='a b'; ["$x" = 'a b' ] :posix等价物
= 好的。[[ ab = a? ]] :是的,因为它进行模式匹配(* ? [ 是魔法)。不全局扩展到当前目录中的文件。[ ab = a? ] :a? 全球扩张。因此,根据当前目录中的文件,可能为真或假。[ ab = a\? ] 错误,不是全局扩展= 和== 在[ 和[[ 中是相同的,但== 是bash扩展。case ab in (a?) echo match; esac :posix等价物- 以东十一〔58〕假,与以东十一〔59〕失去魔力。
[[ ab? =~ 'ab?' ]] 对
=~ 好的。[[ ab =~ ab? ]] 为真,posix扩展正则表达式匹配,? 不全局扩展[ a =~ a ] :语法错误。没有等价的bash。printf 'ab :POSIX等效(仅限单线数据)
' | grep -Eq 'ab?'awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?' :posix等价物。
建议:务必使用
我见过的每个
如果您使用
- 失去可移植性
- 强迫读者学习另一个bash扩展的复杂性。
[ 只是一个有着奇怪名字的常规命令,不涉及特殊的语义。
1灵感来源于Korn Shell中等效的
2.但是对于
3.对于
在bash 3.2及更高版本中为4,且未启用与bash 3.1的兼容性(与
5.尽管分组(这里使用
用于状态测试的单个支架内(即])一些运算符(如single
用于状态测试的双括号内(即]])在新旧外壳中使用
编辑:我还应该注意:在bash中,总是使用双括号[……]]如果可能的话,因为它比单个支架更安全。我将通过以下示例说明原因:
1 | if [ $var =="hello" ]; then |
如果$var恰好为空,那么脚本将看到:
1 | if [ =="hello" ]; then |
这会破坏你的剧本。解决方案是使用双括号,或者总是记住在变量周围加引号(
见
http://mywiki.wooledge.org/bashfaq/031和http://mywiki.wooledge.org/bashguide/testsandconditionals
除非你是为posix sh写的,否则我们推荐
bash手册上说:
When used with [[, the ‘<’ and ‘>’ operators sort lexicographically
using the current locale. The test command uses ASCII
ordering.
(TEST命令与[]相同)
您可以使用双方括号进行light regex匹配,例如:
(只要您使用的bash版本支持此语法)