Bash if语句何时需要使用方括号?


78

通常,我在if语句中使用方括号:

if [ "$name" = 'Bob' ]; then ...

但是,当我检查是否grep成功时,不使用方括号:

if grep -q "$text" $file ; then ...

if声明中什么时候需要方括号?


1
单方括号跨多个外壳兼容,但是其中的一些外壳(包括Bash)支持首选的双方括号。有关更多信息,请参见BashFAQ / 031。另请参阅help '['
丹尼斯·威廉姆森

Answers:


127

方括号是test命令的同义词。一条if语句检查命令的退出状态,以便决定采用哪个分支。grep -q "$text"是命令,但"$name" = 'Bob'不是-它只是一个表达式。test是一个命令,它接受一个表达式并对其求值:

if test "$name" = 'Bob'; then ...

由于方括号是test命令的同义词,因此您可以将其重写为原始语句:

if [ "$name" = 'Bob' ]; then ...

2
@chepner:为什么if $boolean_var ; then ...不需要括号?
米莎·莫罗什科

10
@misha,如果您$boolean_var的值为“ true”或“ false”,则可以运行该命令 ,因为您正在运行命令truefalse
glenn jackman 2012年

4
if $boolean_var ; then ...如果$ boolean_var为01,则无法正常工作,请参见man trueman false
derFunk 2014年

@derFunk:如果你碰巧有它的工作0,并1在你的命令$PATH-但是这将是丑陋的。
基思·汤普森

spellcheck不喜欢方括号,但可以与VSCode中的测试语句一起使用。
johnrubythecat

32

[实际上是一个命令,等同于该test命令(几乎见下文)。它不是shell语法的一部分。([test,这取决于外壳,通常也是内置命令,但这不会影响它们的行为,除非可能是为了提高性能。)

一个if语句执行的命令和执行then如果命令成功的一部分,或者else一部分(如果有的话),如果它失败。(如果命令以状态($?)为0退出,则成功;如果以非零状态退出,则失败。)

if [ "$name" = 'Bob' ]; then ...

命令是

[ "$name" = 'Bob' ]

(您可以直接执行同一命令,而无需使用if。)

if grep -q "$text" $file ; then ...

命令是

grep -q "$text" $file

man [man test了解更多信息。

脚:嗯,该[命令几乎等同于该test命令。区别在于,[要求]以其作为最后一个参数,而test实际上并不允许-(更确切地说,test不对]参数进行特殊处理;例如,它可以是有效的文件名)。(不必以这种方式实施,但是如果[没有匹配项,]就会使很多人非常紧张。)


拼写检查不喜欢方括号,但可以与VSCode中的测试语句一起使用。
johnrubythecat

1
@johnrubythecat:您指的是“拼写检查”?如果要拼写检查英文文本,那么对shell语法当然不会感到满意。
基思·汤普森

再加上一个nervous参数。
Timo

10

[ ... ]考虑语法的最佳方法是考虑[成为一个程序-它就是它!

看一下这个:

~ $ ls /usr/bin/\[ 
/usr/bin/[

另一方面,您可能没有使用该版本,因为bash它还提供了[作为内置的shell。

无论如何,要回答您的问题:什么if是运行您给它的命令,并查看它的返回值是否是0。您[可以进行其他更有趣的比较,例如字符串比较。请参阅man [man bash


bash手册页中没有任何内容表明[是在内部实现的,我认为这[[就是要实现的。
PhilHibbs 2012年

@PhilHibbs:我很确定这[是内置的。这就是为什么builtin [[[与有所不同[,它做不同的事情。
cha0site 2012年

@PhilHibbs:在bash手册页的SHELL BUILTIN COMMANDS下查看。test expr[ expr ]一起列出。
chepner 2012年

1
@PhilHibbs:另外,请尝试type -a [
Keith Thompson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.