Bash 中的 [ 和 [[ 有啥区别? [复制]

Posted

技术标签:

【中文标题】Bash 中的 [ 和 [[ 有啥区别? [复制]【英文标题】:What's the difference between [ and [[ in Bash? [duplicate]Bash 中的 [ 和 [[ 有什么区别? [复制] 【发布时间】:2011-03-26 13:35:55 【问题描述】:

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

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

【问题讨论】:

@AnthonyRutledge 你能说得更具体些吗?为什么? 对于那些想知道要输入什么来查看-n-z-ge-eq-d 等手册页的人,答案是@987654331 @. 【参考方案1】:

最重要的区别是代码的清晰度。是的,是的,上面说的是真的,但是 [[ ]] 使您的代码符合您对高级语言的期望,尤其是在 AND (&& strong>)、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 ...

【讨论】:

虽然其他答案在技术上是正确的,但这是唯一一个完全正确的答案。 “最重要的区别将是你的代码的清晰度。”:不,区别在于[是一个命令,而[[是一个语法元素(“保留字”) .因此不同的解析。 没有?我只是说实际的区别。 [[ ]]let 的捷径,如果我没记错的话。归根结底,确实存在语法差异,但对于外行来说,最重要的是易于阅读和可维护性。因此,这就是为什么我说“最重要”,而不是“仅”或“按书本”的区别。【参考方案2】:

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

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

    if [ -f "$file" ]
    

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

    if [[ -f $file ]]
    

    因为它是一种语法特性,它允许您使用 &&|| 运算符进行布尔测试,并使用 <> 进行字符串比较。 [ 无法执行此操作,因为它是常规命令,并且 &&||<> 不会作为命令行参数传递给常规命令。

    它有一个很棒的=~ 运算符来进行正则表达式匹配。使用[ 你可以写

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

    [[ 可以这样写

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

    它甚至可以让您访问它存储在BASH_REMATCH 中的捕获组。例如,如果您在上面输入完整的“yes”,$BASH_REMATCH[1] 将是“es”。

    您可以免费获得模式匹配,也就是 globbing。也许你对如何输入yes 不那么严格。如果用户键入 y-anything,也许你没问题。为您服务:

    if [[ $ANSWER = y* ]]
    

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

另见

Bash FAQ - "What is the difference between test, [ and [[ ?" Bash Practices - Bash Tests Server Fault - What is the difference between double and single brackets in bash?

【讨论】:

很好,除了 [[ 也存在于 ksh 和最近的 POSIX sh 规范中。 FWIW,可以进入[[[ 的条件表达式集(如-f-z 等)的参考位于Bash Reference Manual: Bash Conditional Expressions @Darron 我在特定服务器中使用 Ubuntu,而我的 sh(实际上是 dash 版本 0.5.8)不支持 [[ @Darron 在这里 pubs.opengroup.org/onlinepubs/9699919799/utilities/… 它存在,但是,没有指定行为,因此当需要 POSIX 合规性时不能依赖它。【参考方案3】:

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

【讨论】:

【参考方案4】: [ 与内置的 test 相同,并且像 test 二进制文件一样工作(人工测试) 在许多类似 UNIX 的环境中的所有其他基于 sh 的 shell 中的工作方式与 [ 大致相同 仅支持单一条件。使用 bash &&|| 运算符的多个测试必须放在单独的括号中。 本身不支持“非”运算符。要反转条件,请在第一个括号外使用 !,以使用 shell 的功能反转命令返回值。 ==!= 是文字字符串比较 [[ 是一个 bash 是特定于 bash 的,尽管其他 shell 可能已经实现了类似的结构。不要指望它会出现在老式的 UNIX sh 中。 ==!= 应用 bash 模式匹配规则,请参阅 man bash 中的“模式匹配” 有一个=~ 正则表达式匹配运算符 允许使用括号和括号内的!&&|| 逻辑运算符来组合子表达式

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

【讨论】:

测试支持使用 -a 和 -o 的多个条件。此外,它有一个非运算符,例如如果 [ ! -z x ];然后回显 Y;菲

以上是关于Bash 中的 [ 和 [[ 有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Bash shell 中的 $var、"$var" 和 "$var" 有啥区别?

python中的b''和''有啥区别? [复制]

python中的range和xrange有啥区别? [复制]

RequireJS中的define和require有啥区别? [复制]

TypeScript 中的 function 和 => 有啥区别? [复制]

Ruby 中的“包含模块”和“扩展模块”有啥区别? [复制]