【发布时间】:2014-10-15 23:56:31
【问题描述】:
我对 bash 脚本中的 if 语句有一个微妙的问题:“if”后面应该使用什么类型的括号?
我现在有两个语句都可以工作,但如果我交换 () 和 [] 则不起作用。
1.比较变量名
NAME="dada"
if [ "$NAME" == "dada" ]; then SOME COMMANDS; fi
如果将[]改为(),错误:
dada: command not found
2.使用grep
if ( grep -q "lalala" mytest.txt ); then SOME COMMANDS; fi
如果将()改为[],错误:
[: lalala: binary operator expected
我阅读了 linux man,其中建议使用 []。那么是因为使用了grep吗?能不能说如果在if里面使用另外一个程序,我们应该使用()?
关于双引号的附带问题, 是否有必要在 shell 中引用文本?例如,echo "$NAME" 或 NAME="fadfaj"?
我很困惑,因为当我尝试使用 $NAME 加上一些特殊字符(例如“_”或空格,而我需要使用“\”)时,使用和不使用“”时我得到了不同的行为。
NAME="myfolder"
echo $NAME\_na
echo "$NAME\_na"
输出
myfolder_na
myfolder\_na
我知道这些都是幼稚的问题,但我非常感谢您的所有帮助!
【问题讨论】:
-
顺便说一下,POSIX不需要
test命令支持==作为操作符(一些shell,比如bash,支持作为扩展),所以使用起来更安全=代替。 -
...顺便说一句,不要使用括号,除非您想要它们的效果(创建子shell)。
if (foo)比if foo慢,因为它派生了一个子进程,在该子进程内运行foo,然后检查子shell 的返回值。这也意味着,与if cd directory; the ...不同——它实际上 确实 更改了当前 shell 中的目录,并根据它是否成功进行了分支——if (cd directory); then ...实际上不会更改目录你所在的 shell,因为它在子进程中执行cd,而不是主 shell。 -
如果你想要一个没有有副作用的分组操作符,那就是花括号,而不是括号。所以:
false || {something; something-else; }比false || (something; something-else)更有效。 -
顺便说一句——不要将额外的问题编辑到一个 SO 主题中。如果您有更多问题,请搜索是否有其他人已经问过,如果没有其他人,请单独询问。否则,您的问题可能会因过于宽泛而被关闭。
-
非常感谢您提供关于 shell 的额外 cmets/教程!它有很大的帮助,并且可能使我免于将来的调试!我会小心不要在一篇文章中提出多个问题。