在Bash中[和[]有什么区别?

我查看了bash手册页,[[说它使用条件表达式。然后我查看了条件表达式部分,它列出了与test(和[)相同的操作符。

所以我想知道,Bash中的[[[之间的区别是什么?

185356 次浏览

在bash中,与[相反,[[防止变量值的分词。

[[是bash对[命令的改进。如果您编写以bash为目标的脚本,它有几个增强功能,使其成为更好的选择。我最喜欢的是:

  1. 它是shell的一个语法特征,所以它有一些[没有的特殊行为。你不再需要疯狂地引用变量,因为[[更直观地处理空字符串和有空格的字符串。例如,对于[,您必须编写

    if [ -f "$file" ]
    

    正确处理空字符串或包含空格的文件名。对于[[,引号是不必要的:

    if [[ -f $file ]]
    
  2. Because it is a syntactical feature, it lets you use && and || operators for boolean tests and < and > for string comparisons. [ cannot do this because it is a regular command and &&, ||, <, and > are not passed to regular commands as command-line arguments.

  3. It has a wonderful =~ operator for doing regular expression matches. With [ you might write

    if [ "$answer" = y -o "$answer" = yes ]
    

    [[中,你可以这样写

    if [[ $answer =~ ^y(es)?$ ]]
    

    它甚至允许你访问它存储在BASH_REMATCH中的捕获组。例如,如果你在上面键入完整的“yes”,${BASH_REMATCH[1]}将是“es”

  4. 你得到模式匹配也就是免费的globbing。也许你对如何输入“是”没有那么严格。如果用户输入y-任何,你都没问题。让你知道:

    if [[ $ANSWER = y* ]]
    

Keep in mind that it is a bash extension, so if you are writing sh-compatible scripts then you need to stick with [. Make sure you have the #!/bin/bash shebang line for your script if you use double brackets.

See also

  • [与内置的test相同,工作方式类似于test二进制(man test)
    • 在许多类unix环境中,[的工作原理与所有其他基于sh的shell中的[相同
    • 只支持单一条件。使用bash &&||操作符的多个测试必须放在单独的括号中。
    • 不支持“not”操作符。要反转一个条件,在第一个括号外使用!来使用shell的功能来反转命令返回值。
    • ==!=是字面值字符串比较
    • 李< / ul > < / >
    • [[是一个bash
      • 是特定于bash的,尽管其他shell可能已经实现了类似的构造。不要指望在老式的UNIX sh中使用它。
      • ==!=应用bash模式匹配规则,请参见man bash中的“模式匹配”
      • =~正则表达式匹配操作符
      • 允许使用括号和括号内的!&&||逻辑运算符来组合子表达式
      • 李< / ul > < / >

      除此之外,它们非常相似——大多数单独的测试在它们之间的工作方式相同,只有当您需要将不同的测试与逻辑AND/OR/NOT操作结合在一起时,事情才会变得有趣。

最重要的区别是代码的清晰。是的,是的,上面所说的是正确的,但是[[]]使你的代码符合你在高级语言中所期望的,特别是关于AND (,,), OR (||)和NOT ()操作符。因此,当您在系统和语言之间切换时,您将能够更快地解释脚本,从而使您的生活更轻松。从好的UNIX/Linux参考中获取基本信息。你可能会发现一些细节在某些情况下是有用的,但你会一直欣赏清晰的代码!你更愿意读哪个剧本片段?即使断章取义,第一种选择也更容易阅读和理解。


if [[ -d $newDir && -n $(echo $newDir | grep "^${webRootParent}") && -n $(echo $newDir | grep '/$') ]]; then ...

if [ -d "$newDir" -a -n "$(echo "$newDir" | grep "^${webRootParent}")" -a -n "$(echo "$newDir" | grep '/$')" ]; then ...