AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 52034
Accepted
0x89
0x89
Asked: 2009-08-10 13:11:51 +0800 CST2009-08-10 13:11:51 +0800 CST 2009-08-10 13:11:51 +0800 CST

bash中的双方括号和单方括号有什么区别?

  • 772

我只是想知道两者之间到底有什么区别

[[ $STRING != foo ]]

和

[ $STRING != foo ]

是,除了后者是 POSIX 兼容的,在 sh 中找到,而前者是在 bash 中找到的扩展。

scripting bash shell posix
  • 5 5 个回答
  • 260914 Views

5 个回答

  • Voted
  1. Best Answer
    Kyle Brandt
    2009-08-10T13:56:00+08:002009-08-10T13:56:00+08:00

    有几个不同之处。在我看来,最重要的几个是:

    1. [是 Bash 和许多其他现代 shell 中的内置函数。内置[函数类似于test关闭的附加要求]。内置函数[和test模仿功能/bin/[以及/bin/test它们的限制,以便脚本向后兼容。最初的可执行文件仍然存在,主要是为了 POSIX 合规性和向后兼容性。在 Bash 中运行该命令type [表示[默认情况下将其解释为内置命令。(注:只在PATHwhich [上查找可执行文件,相当于.可以执行查看详情)type -P [type --help
    2. [[不兼容,它不一定适用于任何/bin/sh指向。[[更现代的 Bash / Zsh / Ksh 选项也是如此。
    3. 因为[[内置在 shell 中并且没有遗留要求,所以您无需担心基于IFS变量的分词会弄乱评估为带有空格的字符串的变量。因此,您实际上不需要将变量放在双引号中。

    在大多数情况下,其余的只是一些更好的语法。要查看更多差异,我推荐此链接到常见问题解答:测试、[ 和 [[ 之间有什么区别?. 事实上,如果您对 bash 脚本很认真,我建议您阅读整个wiki,包括 FAQ、Pitfalls和 Guide。 指南部分的测试部分也解释了这些差异,以及为什么作者认为[[如果您不需要担心便携性是更好的选择。主要原因是:

    1. 您不必担心引用测试的左侧,以便它实际上被读取为变量。
    2. 您不必< >使用反斜杠转义小于和大于,以免它们被评估为输入重定向,这可能会通过覆盖文件而真正搞砸一些东西。这又回到[[了内置。如果 [ (test) 是一个外部程序,那么 shell 将不得不以它的评估方式进行异常处理,<并且>只有在/bin/test被调用时才会发生异常,这实际上没有任何意义。
    • 375
  2. abhiomkar
    2010-12-30T11:42:25+08:002010-12-30T11:42:25+08:00

    简而言之:

    [ 是一个 bash内置

    [[ ]] 是 bash关键字

    关键字:关键字很像内置函数,但主要区别在于特殊的解析规则适用于它们。例如, [ 是 bash 内置函数,而 [[ 是 bash 关键字。它们都用于测试东西,但由于 [[ 是关键字而不是内置的,它受益于一些特殊的解析规则,这使得它更容易:

      $ [ a < b ]
     -bash: b: No such file or directory
      $ [[ a < b ]]
    

    第一个示例返回错误,因为 bash 尝试将文件 b 重定向到命令 [ a ]。第二个例子实际上做了你所期望的。字符 < 不再具有文件重定向运算符的特殊含义。

    资料来源: http: //mywiki.wooledge.org/BashGuide/CommandsAndArguments

    • 159
  3. Ciro Santilli OurBigBook.com
    2015-07-13T02:22:47+08:002015-07-13T02:22:47+08:00

    行为差异

    Bash 4.3.11 的一些区别:

    • POSIX 与 Bash 扩展:

      • [ 是 POSIX
      • [[ 是一个受 Korn shell 启发的 Bash 扩展
    • 常规命令与魔法

      • [只是一个带有奇怪名称的常规命令。

        ]只是 的最后一个参数[。

      Ubuntu 16.04 实际上有一个/usr/bin/[由coreutils提供的可执行文件,但 bash 内置版本优先。

      Bash 解析命令的方式没有任何改变。

      特别是,<是重定向,&&并||连接多个命令,( )生成子shell,除非转义\,并且单词扩展照常发生。

      • [[ X ]]是一个X可以神奇地解析的单一结构。<, &&,||和()被特殊对待,分词规则不同。

        还有更多的区别,如=和=~。

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

    • <

      • [[ a < b ]]: 字典比较
      • [ a \< b ]: 同上。\required 或者像任何其他命令一样进行重定向。Bash 扩展。
      • expr x"$x" \< x"$y" > /dev/null或[ "$(expr x"$x" \< x"$y")" = 1 ]:POSIX 等效项,请参阅:https ://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989
    • &&和||

      • [[ a = a && b = b ]]: 真实的,合乎逻辑的
      • [ a = a && b = b ]: 语法错误,&&解析为 AND 命令分隔符cmd1 && cmd2
      • [ a = a ] && [ b = b ]: POSIX 可靠等价物
      • [ a = a -a b = b ]a: 几乎等价,但被 POSIX 弃用,因为它是疯狂的,并且对于or blike !or的某些值会失败,或者(将被解释为逻辑操作
    • (

      • [[ (a = a || a = b) && a = b ]]: 错误的。没有( ), 会是真的,因为[[ && ]]它的优先级高于[[ || ]]
      • [ ( a = a ) ]: 语法错误,()被解释为子shell
      • [ \( a = a -o a = b \) -a a = b ]: 等效,但是(), -a, 和-o被 POSIX 弃用。没有\( \)会是真的,因为-a优先级高于-o
      • { [ a = a ] || [ a = b ]; } && [ a = b ]不推荐使用的 POSIX 等效项。然而,在这种特殊情况下,我们可以写成:[ a = a ] || [ a = b ] && [ a = b ]因为||和&&shell 运算符具有相同的优先级,不像[[ || ]]and[[ && ]]和-o, -aand[
    • 扩展时的分词和文件名生成 (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? ]]:是的,因为它会进行模式匹配(* ? [很神奇)。不 glob 扩展到当前目录中的文件。
      • [ ab = a? ]: a?glob 扩展。所以可能是真或假,具体取决于当前目录中的文件。
      • [ ab = a\? ]: false,不是全局扩展
      • =and在and==中是相同的,但是是一个 Bash 扩展。[[[==
      • case ab in (a?) echo match; esac: POSIX 等价物
      • [[ ab =~ 'ab?' ]]: false,''在 Bash 3.2 及更高版本中失去魔力,并且未启用对 bash 3.1 的兼容性(如 with BASH_COMPAT=3.1)
      • [[ ab? =~ 'ab?' ]]: 真的
    • =~

      • [[ ab =~ ab? ]]: true,POSIX扩展正则表达式匹配,?不全局扩展
      • [ a =~ a ]: 语法错误。没有 bash 等价物。
      • printf 'ab\n' | grep -Eq 'ab?': POSIX 等效项(仅单行数据)
      • awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?': POSIX 等价物。

    建议:一直使用[]

    [[ ]]我见过的每个构造都有 POSIX 等价物。

    如果你使用[[ ]]你:

    • 失去便携性
    • 迫使读者了解另一个 bash 扩展的复杂性。[只是一个名称怪异的常规命令,不涉及特殊语义。

    感谢Stéphane Chazelas的重要更正和补充。

    • 102
  4. Premraj
    2016-02-08T19:15:42+08:002016-02-08T19:15:42+08:00

    Single Bracket ie[]是符合 POSIX shell 的,用于包含条件表达式。

    双括号ie[[]]是标准 POSIX 版本的增强(或扩展)版本,这由 bash 和其他 shell(zsh,ksh)支持。

    在 bash 中,我们使用eq, ne, ltand进行数值比较gt,用双括号进行比较我们可以使用==, !=,<,和>字面意思。

    • [是测试命令的同义词。即使它内置在 shell 中,它也会创建一个新进程。
    • [[是它的新改进版本,它是一个关键字,而不是一个程序。

    例如:

    [ var1 lt var2] #works
    [ var1 < var2] #error: var2 No such file or directory 
    [ var1 \< var2] #works with escape
    [[ var1 < var2]] #works
    
    • 18
  5. womble
    2009-08-10T13:17:58+08:002009-08-10T13:17:58+08:00

    基于对手册页相关部分的快速阅读,主要区别似乎是==and!=运算符匹配模式,而不是文字字符串,并且还有=~正则表达式比较运算符。

    • 9

相关问题

  • 知道任何适用于 Windows 的快速可编写脚本的 ftp 客户端吗?[关闭]

  • 如果同一个任务已经在运行,如何防止计划任务运行?

  • 需要从 Batch For 循环中排除特定结果

  • Bash 脚本:要求脚本以 root 身份运行(或使用 sudo)

  • 从命令行删除旧的(非引导)Windows Vista 目录

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    Windows 中执行反向 DNS 查找的命令行实用程序是什么?

    • 14 个回答
  • Marko Smith

    如何检查 Windows 机器上的端口是否被阻塞?

    • 4 个回答
  • Marko Smith

    我应该打开哪个端口以允许远程桌面?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch 如何更改我的私钥密码? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve