[和[[在Bash?之间]有什么区别?

bod*_*ydo 323 bash

我查看了bash手册页,并[[说它使用条件表达式.然后我查看了Conditional Expressions部分,它列出了与test(和[)相同的运算符.

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

Joh*_*ica 475

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

  1. 它是shell的一个语法特性,因此它有一些[不具备的特殊行为.您不再需要引用像mad这样的变量,因为[[更直观地处理空字符串和带有空格的字符串.例如,[你必须写

    if [ -f "$file" ]
    
    Run Code Online (Sandbox Code Playgroud)

    正确处理空字符串或带有空格的文件名.随着[[引号是不必要的:

    if [[ -f $file ]]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 因为它是一个语法功能,它可以让你使用&&||布尔测试和运营商<>字符串比较.[做不到这一点,因为这是一个普通的命令 &&,||,<,并>不会传递到常规命令作为命令行参数.

  3. 它有一个很棒的=~运算符来进行正则表达式匹配.随[你可能会写

    if [ "$answer" = y -o "$answer" = yes ]
    
    Run Code Online (Sandbox Code Playgroud)

    随着[[你可以写为

    if [[ $answer =~ ^y(es)?$ ]]
    
    Run Code Online (Sandbox Code Playgroud)

    它甚至允许您访问其存储的捕获组BASH_REMATCH.例如,${BASH_REMATCH[1]}如果您在上面输入完整的"是",则为"es".

  4. 你得到模式匹配aka globbing免费.也许你对如何键入yes不太严格.如果用户键入y-anything,也许你没问题.你知道了:

    if [[ $ANSWER = y* ]]
    
    Run Code Online (Sandbox Code Playgroud)

请记住,它是一个bash扩展,所以如果你正在编写sh兼容的脚本,那么你需要坚持下去[.#!/bin/bash如果使用双括号,请确保脚本中有shebang行.

也可以看看

  • 好,除了[[也存在于ksh和最近的POSIX sh规范中). (13认同)

Wal*_*ndt 26

  • [test内置相同,并且像test二进制(man test)一样工作
    • [许多类UNIX环境中的所有其他基于sh的shell一样
    • 仅支持单一条件.使用bash &&||运算符进行多次测试必须在单独的括号中.
    • 本身不支持'not'运算符.要反转条件,请使用!第一个括号外部来使用shell的工具来反转命令返回值.
    • ==并且!=是文字字符串比较
  • [[ 是一个bash
    • 是特定于bash的,尽管其他shell可能已经实现了类似的构造.不要指望它在老式的UNIX sh中.
    • ==!=应用bash模式匹配规则,请参阅"模式匹配"man bash
    • 有一个=~正则表达式匹配运算符
    • 允许使用括号和括号内的!,&&||逻辑运算符来组合子表达式

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

  • test使用-a和-o支持多个条件.此外,它有一个非运算符,例如,如果[!-zx]; 然后回声Y; 科幻 (6认同)

Xav*_* V. 7

在bash中,与之相反[,[[可以防止变量值的单词拆分.


Ant*_*dge 6

最重要的区别在于代码的清晰度.是的,是的,上面说的是真的,但是[[]]使你的代码符合你在高级语言中所期望的,特别是关于AND(&&),OR(||)和NOT(!)运营商.因此,当您在系统和语言之间移动时,您将能够更快地解释脚本,从而使您的生活更轻松.从一个好的UNIX/Linux参考中获取细节.您可能会发现某些细节在某些情况下有用,但您将始终欣赏清晰的代码!您更喜欢阅读哪个脚本片段?即使脱离背景,第一选择也更容易阅读和理解.


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

要么

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

  • 尽管其他答案在技术上都是正确的,但这是唯一完全正确的答案。 (2认同)