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中的range和xrange有啥区别? [复制]
RequireJS中的define和require有啥区别? [复制]