一个共同工作人员声称最近在码的审查, [[ ]] 建构是可以优先选 [ ] 在像构造

if [ "`id -nu`" = "$someuser" ] ; then 
     echo "I love you madly, $someuser"
fi

他不能提供理由。是有一个吗?

有帮助吗?

解决方案

[[ 有减少惊喜和一般使用更安全。但它不是便携式-POSIX不指定用它做什么,只有一些贝壳的支持(旁边的庆典,我听到些支持它太)。例如,你可以做的

[[ -e $b ]]

要测试一个文件是否存在。但与 [, 你有的话 $b, ,因为它分割的论点和扩大的东西喜欢 "a*" (在那里 [[ 把它从字面上).这也与如何 [ 可能是一个外部程序和接收其参数通常只是喜欢每一个其他程序(虽然它也可以是一个内建的,但它仍然没有这个特殊的处理)。

[[ 还有其他一些不错的功能,像经常表达的匹配 =~ 随着经营者象他们是已知的在C-喜欢的语言。这里是一个良好的网页: 之间的区别是什么测试 [[[ ?砸向试验

其他提示

行为差异

一些差异在Bash4.3.11:

  • POSIX vs Bash扩展:

  • 常规命令vs魔法

    • [ 是只是一个普通的命令有一个奇怪的名字。

      ] 只是一个说法的 [ 这可以防止进一步的辩论正在被使用。

      Ubuntu的16.04实际上具有可执行它在 /usr/bin/[ 提供下载管理器,各种文件下载,但bash建版本优先。

      没有什么改变的方式,庆典分析的命令。

      特别是, < 正重定向 &&|| 连接的多个命令, ( ) 生子shell,除非通过逃脱的 \, 和word膨胀发生的一切如常。

    • [[ X ]] 是一个单一的结构,使得 X 分析神奇。 <, &&, ||() 是经过特殊处理,并字分裂的规则是不同的。

      还有进一步的差异样 ==~.

      在Bashese: [ 是一个内置命令,和 [[ 是一个关键词: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • &&||

    • [[ a = a && b = b ]]:真的,逻辑
    • [ a = a && b = b ]:语法错误, && 分析为一个和分隔的命令 cmd1 && cmd2
    • [ a = a -a b = b ]:相当,但deprecated通过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 equivalent⁵
  • 字分割和文件的生成应扩展(分+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? ]]:真的,因为它不会 模式匹配 (* ? [ 是魔术).不glob扩大到文件在当前的目录。
    • [ ab = a? ]: a? glob扩大。所以可能是真实的或虚假的,根据该文件,在当前的目录。
    • [ ab = a\? ]:假,不glob膨胀
    • === 是同在这两个 [[[, 但 == 是砸扩展。
    • case ab in (a?) echo match; esac:POSIX等
    • [[ ab =~ 'ab?' ]]:false⁴,失去魔法 ''
    • [[ ab? =~ 'ab?' ]]:真的
  • =~

    • [[ ab =~ ab? ]]:真的,POSIX 延长经常表达 匹配, ? 不扩大滴
    • [ a =~ a ]:语法错误。没有庆典等同的。
    • printf 'ab\n' | grep -Eq 'ab?':POSIX当量(单线数据)
    • awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?':POSIX等同的。

建议:总是用 [].

有POSIX当量为每 [[ ]] 建造我见过的。

如果你使用 [[ ]] 你:

  • 失去可携带性
  • 迫使读者了解错综复杂的另一个bash扩展。 [ 是只是一个普通的命令有一个奇怪的名字,没有特殊的语义的参与。

1的启发,从相当于 [[...]] 建造在Korn壳

2但是失败对于有些价值观的 ab (喜欢 +index)并不比较数字如果 ab 看起来像小数整数。 expr "x$a" '<' "x$b" 工作围绕两个。

3和也失败对于有些价值观的 ab 喜欢 !(.

原生在bash3.2和上述和提供的兼容性来砸3.1未启用(如与 BASH_COMPAT=3.1)

⁵虽然分组(这里的 {...;} 命令组,而不是的 (...) 这将运行的不必要的子shell)是不必要的,因为 ||&& 壳运营商(而不是的 ||&& [[...]] 经营者或 -o/-a [ 经营者)拥有同等优先。所以 [ a = a ] || [ a = b ] && [ a = b ] 会是同等的。

[[ ]]具有更多的功能 - 我建议你去看看高级Bash脚本编程指南更多的信息,特别是 扩展测试命令 第7章测试部分。

顺便提及,作为引导记录,[[ ]]在ksh88(1988年版Korn外壳的)。

引入

其中比较器、测试、支架或双架,是最快? (http://bashcurescancer.com)

双架是一个"复合 命令"作为测试和单 支架是外壳内置程序(在 实际上是相同的命令)。因此, 这个支架和双重支架 执行不同的代码。

测试和单个支架是 最便携式,因为他们的存在 独立和外部的命令。然而,如果您使用的任何远程 现代版的庆典,双 支架支持。

在这里你不能使用[典型的情况是在自动工具configure.ac脚本,有括号具有特殊和不同的意义,所以你将不得不使用test代替[或[ - 请注意,测试和[是相同的程序。

如果你到以下 谷歌的风格指导:

试验,[并[[

[[...]]减少错误,因为没有路径扩展字或分裂之间发生[[和]]和[[...]]允许为经常表达的匹配,其中[... 不不是。

# This ensures the string on the left is made up of characters in the
# alnum character class followed by the string name.
# Note that the RHS should not be quoted here.
# For the gory details, see
# E14 at https://tiswww.case.edu/php/chet/bash/FAQ
if [[ "filename" =~ ^[[:alnum:]]+name ]]; then
  echo "Match"
fi

# This matches the exact pattern "f*" (Does not match in this case)
if [[ "filename" == "f*" ]]; then
  echo "Match"
fi

# This gives a "too many arguments" error as f* is expanded to the
# contents of the current directory
if [ "filename" == f* ]; then
  echo "Match"
fi

[[]]双括号是某些版本的SunOS和通过完全不支持的内部函数声明的下不受支持: GNU bash中,版本2.02.0(1)-release(Sun SPARC的-solaris2.6)

概括地说,[[比较好,因为它不会叉的另一过程。没有括号或单个托架比双托架,因为它fork另一个进程慢。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top