Linux bash 双括号问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9666102/
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
bash double bracket issue
提问by lots_of_questions
I'm very new to bash scripting and am running into an issue when using double brackets. I can't seem to get them to work at all in Ubuntu Server 11.10. My script below is in if_test.sh.
我对 bash 脚本很陌生,在使用双括号时遇到了问题。我似乎无法让它们在 Ubuntu Server 11.10 中工作。我下面的脚本在 if_test.sh 中。
#!/bin/bash
if [[ "14"=="14" ]]; then
echo "FOO"
fi
When I run this simple shell script the output I get is: if_test.sh: 5: [[: not found
当我运行这个简单的 shell 脚本时,我得到的输出是: if_test.sh: 5: [[: not found
It seems that I'm running GNU bash version 4.2.10 after running bash --version from the terminal. Any help would be greatly appreciated. Thanks!
从终端运行 bash --version 后,我似乎正在运行 GNU bash 版本 4.2.10。任何帮助将不胜感激。谢谢!
采纳答案by Frédéric Hamidi
The problem lies in your script invocation. You're issuing:
问题在于您的脚本调用。你发出:
$ sudo sh if_test.sh
On Ubuntu systems, /bin/sh
is dash
, not bash
, and dash
does not support the double bracket keyword (or didn't at the time of this posting, I haven't double-checked). You can solve your problem by explicitly invoking bash
instead:
在 Ubuntu 系统上,/bin/sh
is dash
、 notbash
和dash
不支持双括号关键字(或者在发布时不支持,我没有仔细检查过)。您可以通过显式调用bash
来解决您的问题:
$ sudo bash if_test.sh
Alternatively, you can make your script executable and rely on the shebang line:
或者,您可以使脚本可执行并依赖于shebang 行:
$ chmod +x if_test.sh
$ sudo ./if_test.sh
Also note that, when used between double square brackets, ==
is a pattern matching operator, not the equality operator. If you want to test for equality, you can either use -eq
:
另请注意,在双方括号之间使用时,==
是模式匹配运算符,而不是相等运算符。如果要测试相等性,可以使用-eq
:
if [[ "14" -eq "14" ]]; then
echo "FOO"
fi
或双括号:
if (( 14 == 14 )); then
echo "FOO"
fi
回答by William Pursell
Since you are new to scripting, you may be unaware that [[
is a bashism. You may not even know what a bashism is, but both answers given so far are leading you down a path towards a stunted scripting future by promoting their use.
由于您不[[
熟悉脚本,因此您可能不知道这是一种 bashism。您甚至可能不知道 bashism 是什么,但到目前为止给出的两个答案都通过促进它们的使用来引导您走向发育迟缓的脚本未来。
To check if a variable matches a string in any flavor of Bourne shell, you can do test $V = 14
If you want to compare integers, use test $V -eq 14
. The only difference is that the latter will generate an error if $V does not look like an integer. There are good reasons to quote the variable (test "$V" = 14
), but the quotes are often unnecessary and I believe are the root cause of a common confusion, since "14"=="14"
is identical to "14==14"
where it is more obvious that '==' is not being used as an operator.
要检查变量是否与任何风格的 Bourne shell 中的字符串匹配,您可以执行test $V = 14
如果要比较整数,请使用test $V -eq 14
. 唯一的区别是,如果 $V 看起来不像一个整数,后者会产生一个错误。引用变量 ( test "$V" = 14
)有充分的理由,但引号通常是不必要的,我认为这是常见混淆的根本原因,因为"14"=="14"
与"14==14"
更明显的 '==' 未用作运算符的情况相同.
There are several things to note: use a single '=' instead of '==' because not all shells recognize '==', the [
command is identical to test
but requires a final argument of ]
and many sh coding guidelines recommend using test
because it often generates more understandable code, [[
is only recognized by a limited number of shells (this is your primary problem, as your shell does not appear to recognize [[
and is looking for a command of that name. This is surprising if your shebang does indeed specify /bin/bash
instead of /bin/sh
).
有几件事情需要注意:使用一个单一的“=”而不是“==”,因为不是所有的炮弹承认“==”,该[
命令是相同的test
,但需要一个最终的说法]
,许多SH编码指南推荐使用test
往往是因为它生成更易于理解的代码,[[
只能被有限数量的 shell 识别(这是您的主要问题,因为您的 shell 似乎无法识别[[
并正在寻找该名称的命令。如果您的 shebang 确实指定/bin/bash
而不是/bin/sh
)。
回答by Cory Klein
My answer doesn't apply to @lots_of_questions's question specifically, but you can also run into this problem if you have the wrong specifier at the top of your script:
我的回答不适用于@lots_of_questions 的具体问题,但如果脚本顶部的说明符错误,您也可能会遇到此问题:
#!/bin/sh
if [[ ... ]]
...
You should change that to
你应该把它改成
#!/bin/bash
if [[ ... ]]
...