双方括号[[]]优于Bash中的单方括号[]吗?
一位同事最近在一篇代码审查中声称, [[ ]]
结构比结构中的[ ]
要优于[ ]
if [ "`id -nu`" = "$someuser" ] ; then
echo "I love you madly, $someuser"
fi
他无法提供理由。 有一个吗?
[[
减少惊喜,通常更安全。 但它不可移植 - POSIX没有指定它的功能,只有一些shell支持它(除了bash,我听说ksh也支持它)。 例如,你可以做
[[ -e $b ]]
测试文件是否存在。 但是对于[
,你必须引用$b
,因为它分裂了参数并扩展了诸如"a*"
(其中[[
从字面上理解])。 这也与[
可以是外部程序并像其他程序一样接收其参数一样(虽然它也可以是内置的,但是它仍然没有这种特殊的处理)。
[[
也有其他一些很好的功能,比如正则表达式与=~
匹配,以及类似C语言的运算符。 这里有一个很好的网页:测试, [
和[[
? 和Bash测试
[[ ]]
具有更多特性 - 我建议你参考高级Bash脚本指南了解更多信息,特别是第7章中的扩展测试命令部分。测试。
顺便提一下,作为指导性说明, [[ ]]
是在ksh88(Korn shell的1988版[[ ]]
中引入的。
行为差异
首先,我们来分析两者之间的行为差异。 在Bash 4.3.11中测试。
POSIX vs Bash扩展:
[
是POSIX [[
是Bash扩展名 常规命令vs魔术
[
只是一个带有奇怪名字的常规命令。
]
只是[
阻止进一步论证被使用的论据]
。
Ubuntu 16.04在/usr/bin/[
coreutils提供的实际上有一个可执行文件,但bash内置版本优先。
Bash解析命令的方式没有任何改变。
特别是, <
是重定向, &&
和||
连接多个命令, ( )
生成子壳,除非被转义,并且字扩展像往常一样发生。
[[ X ]]
是一个单独的构造,它可以神奇地解析X
<
, &&
, ||
和()
分别处理,分词规则不同。
还有更多的差异,如=
和=~
。
在Bashese中: [
是一个内置命令, [[
是关键字:https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword
<
[[ a < b ]]
:词典对比 [ a < b ]
:同上。
所需或否则重定向像任何其他命令一样。 Bash扩展。 &&
和||
[[ a = a && b = b ]]
:真,逻辑和 [ a = a && b = b ]
:语法错误, &&
解析为AND命令分隔符cmd1 && cmd2
[ a = a -ab = b ]
:相当于POSIX,但不推荐使用 [ a = a ] && [ b = b ]
:POSIX推荐 (
[[ (a = a || a = b) && a = b ]]
:假 [ ( a = a ) ]
:语法错误, ()
被解释为一个子shell [ ( a = a -oa = b ) -aa = b ]
:等效,但()
被POSIX弃用 ([ a = a ] || [ a = b ]) && [ a = b ]
POSIX建议 分词
x='a b'; [[ $x = 'ab' ]]
x='a b'; [[ $x = 'ab' ]]
:真,不需要引号 x='a b'; [ $x = 'ab' ]
x='a b'; [ $x = 'ab' ]
:语法错误,展开为[ ab = 'ab' ]
x='a b'; [ "$x" = 'ab' ]
x='a b'; [ "$x" = 'ab' ]
:等效 =
[[ ab = a? ]]
[[ ab = a? ]]
:真,因为它确实符合模式匹配( * ? [
是魔术)。 不会扩展到当前目录中的文件。 [ ab = a? ]
[ ab = a? ]
: a?
glob扩展。 所以根据当前目录中的文件可能是真或假。 [ ab = a? ]
[ ab = a? ]
:false,不是glob扩展 =
和==
在[
和[[
中是相同的,但==
是Bash扩展。 printf 'ab' | grep -Eq 'a.'
:相当于POSIX ERE [[ ab =~ 'ab?' ]]
[[ ab =~ 'ab?' ]]
:假,失去了魔术''
[[ ab? =~ 'ab?' ]]
[[ ab? =~ 'ab?' ]]
:true =~
[[ ab =~ ab? ]]
[[ ab =~ ab? ]]
:true,POSIX扩展正则表达式匹配, ?
不会扩大 [ a =~ a ]
:语法错误 printf 'ab' | grep -Eq 'ab?'
:相当于POSIX 建议
我更喜欢总是使用[]
。
对于我见过的每个[[ ]]
结构都有POSIX等价物。
如果你使用[[ ]]
你:
[
只是一个带有奇怪名称的常规命令,不涉及特殊的语义。 上一篇: Is double square brackets [[ ]] preferable over single square brackets [ ] in Bash?
下一篇: In Node.js, how do I "include" functions from my other files?