Bash 中的 [ 和 [[ 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3427872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between [ and [[ in Bash?
提问by bodacydo
I looked at bash man page and the [[
says it uses Conditional Expressions. Then I looked at Conditional Expressions section and it lists the same operators as test
(and [
).
我查看了 bash 手册页,并[[
说它使用条件表达式。然后我查看了条件表达式部分,它列出了与test
(和[
)相同的运算符。
So I wonder, what is the difference between [
and [[
in Bash?
所以我想知道,Bash[
和[[
Bash 有什么区别?
回答by John Kugelman
[[
is bash's improvement to the [
command. It has several enhancements that make it a better choice if you write scripts that target bash. My favorites are:
[[
是 bash 对[
命令的改进。如果您编写针对 bash 的脚本,它有几个增强功能,使其成为更好的选择。我最喜欢的是:
It is a syntactical feature of the shell, so it has some special behavior that
[
doesn't have. You no longer have to quote variables like mad because[[
handles empty strings and strings with whitespace more intuitively. For example, with[
you have to writeif [ -f "$file" ]
to correctly handle empty strings or file names with spaces in them. With
[[
the quotes are unnecessary:if [[ -f $file ]]
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.It has a wonderful
=~
operator for doing regular expression matches. With[
you might writeif [ "$answer" = y -o "$answer" = yes ]
With
[[
you can write this asif [[ $answer =~ ^y(es)?$ ]]
It even lets you access the captured groups which it stores in
BASH_REMATCH
. For instance,${BASH_REMATCH[1]}
would be "es" if you typed a full "yes" above.You get pattern matching aka globbing for free. Maybe you're less strict about how to type yes. Maybe you're okay if the user types y-anything. Got you covered:
if [[ $ANSWER = y* ]]
它是 shell 的一个语法特征,因此它具有一些没有的特殊行为
[
。您不再需要像 mad 那样引用变量,因为[[
可以更直观地处理空字符串和带有空格的字符串。例如,[
你必须写if [ -f "$file" ]
正确处理空字符串或带有空格的文件名。随着
[[
引号是不必要的:if [[ -f $file ]]
因为它是一个语法功能,它可以让你使用
&&
和||
布尔测试和运营商<
和>
字符串比较。[
做不到这一点,因为这是一个普通的命令&&
,||
,<
,并>
不会传递到常规命令作为命令行参数。它有一个很好的
=~
运算符来进行正则表达式匹配。随着[
你可以写if [ "$answer" = y -o "$answer" = yes ]
随着
[[
你可以写为if [[ $answer =~ ^y(es)?$ ]]
它甚至可以让您访问它存储在
BASH_REMATCH
. 例如,${BASH_REMATCH[1]}
如果您在上面输入完整的“是” ,则会是“es”。您可以免费获得模式匹配又名通配。也许你对如何输入 yes 不那么严格。如果用户输入 y-anything,也许你没问题。让你覆盖:
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.
请记住,它是一个 bash 扩展,因此如果您正在编写与 sh 兼容的脚本,那么您需要坚持使用[
. #!/bin/bash
如果您使用双括号,请确保您的脚本有shebang 行。
See also
也可以看看
回答by Walter Mundt
[
is the same as thetest
builtin, and works like thetest
binary (man test)- works about the same as
[
in all the other sh-based shells in many UNIX-like environments - only supports a single condition. Multiple tests with the bash
&&
and||
operators must be in separate brackets. - doesn't natively support a 'not' operator. To invert a condition, use a
!
outside the first bracket to use the shell's facility for inverting command return values. ==
and!=
are literal string comparisons
- works about the same as
[[
is a bash- is bash-specific, though others shells may have implemented similar constructs. Don't expect it in an old-school UNIX sh.
==
and!=
apply bash pattern matching rules, see "Pattern Matching" inman bash
- has a
=~
regex match operator - allows use of parentheses and the
!
,&&
, and||
logical operators within the brackets to combine subexpressions
[
与test
内置函数相同,并且像test
二进制文件一样工作(man test)- 与
[
许多类 UNIX 环境中的所有其他基于 sh 的 shell 的工作方式大致相同 - 只支持一个条件。使用 bash
&&
和||
运算符的多个测试必须在单独的括号中。 - 本身不支持“非”运算符。要反转条件,请
!
在第一个括号外使用 a以使用 shell 的工具来反转命令返回值。 ==
和!=
是文字字符串比较
- 与
[[
是一个bash- 是 bash 特定的,尽管其他 shell 可能已经实现了类似的构造。不要指望它会出现在老式的 UNIX sh 中。
==
并!=
应用bash模式匹配规则,参见“模式匹配”man bash
- 有一个
=~
正则表达式匹配运算符 - 允许使用括号和括号内的
!
,&&
和||
逻辑运算符来组合子表达式
Aside from that, they're pretty similar -- most individual tests work identically between them, things only get interesting when you need to combine different tests with logical AND/OR/NOT operations.
除此之外,它们非常相似——大多数单独的测试在它们之间的工作方式相同,只有当您需要将不同的测试与逻辑 AND/OR/NOT 操作结合起来时,事情才会变得有趣。
回答by Anthony Rutledge
The most important difference will be the clarityof your code. Yes, yes, what's been said above is true, but [[ ]]brings your code in line with what you would expect in high level languages, especially in regards to AND (&&), OR (||), and NOT (!) operators. Thus, when you move between systems and languages you will be able to interpret script faster which makes your life easier. Get the nitty gritty from a good UNIX/Linux reference. You may find some of the nitty gritty to be useful in certain circumstances, but you will always appreciate clearcode! Which script fragment would you rather read? Even out of context, the first choice is easier to read and understand.
最重要的区别将是您的代码的清晰度。是的,是的,上面所说的都是正确的,但是[[]]使您的代码符合您在高级语言中所期望的,尤其是在 AND ( &&)、OR ( ||) 和 NOT ( !) 运营商。因此,当您在系统和语言之间切换时,您将能够更快地解释脚本,这让您的生活更轻松。从一个好的 UNIX/Linux 参考中获取细节。您可能会发现某些细节在某些情况下很有用,但您将永远欣赏清晰的代码!您更愿意阅读哪个脚本片段?即使脱离上下文,第一个选择也更容易阅读和理解。
if [[ -d $newDir && -n $(echo $newDir | grep "^${webRootParent}") && -n $(echo $newDir | grep '/$') ]]; then ...
or
或者
if [ -d "$newDir" -a -n "$(echo "$newDir" | grep "^${webRootParent}")" -a -n "$(echo "$newDir" | grep '/$')" ]; then ...
回答by Xavier V.
In bash, contrary to [
, [[
prevents word splitting of variable values.
在 bash 中,与 相反[
,[[
防止对变量值进行分词。