Is double square brackets [[ ]] preferable over single square brackets [ ] in Bash?
一位同事最近在一次代码审查中声称,在类似于
1 2 3 | if ["`id -nu`" ="$someuser" ] ; then echo"I love you madly, $someuser" fi |
他无法提供一个理由。有吗?
1 | [[ -e $b ]] |
测试文件是否存在。但是对于
行为差异好的。
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个
5.尽管分组(这里使用
顺便说一下,正如指南所指出的,ESH88(1988年版的Korn Shell)中引入了
从哪个比较器,测试,支架,或双支架,是最快的?(http://bashcurescancer.com)
The double bracket is a"compound
command" where as test and the single
bracket are shell built-ins (and in
actuality are the same command). Thus,
the single bracket and double bracket
execute different code.The test and single bracket are the
most portable as they exist as
separate and external commands.
However, if your using any remotely
modern version of BASH, the double
bracket is supported.
不能使用[[的典型情况是在autotools configure.ac脚本中,括号有一个特殊的和不同的含义,因此您必须使用
[[]]双括号在特定版本的sunos下不可移植,在函数声明中完全不可移植,方法是:gnu bash,版本2.02.0(1)-发布(sparc-sun-solaris2.6)
简言之,[]更好,因为它不分叉另一个过程。没有括号或单个括号比双括号慢,因为它分叉另一个进程。