为什么[0]进入无限循环?


23

我看到下面的循环与的循环具有相同的行为while [ 1 ]。为什么?

while [ 0 ]; do
    echo "hello"
done

Answers:


33

shell中的单个方括号是的同义词test(单独的命令或内置的shell),因此与[ 0 ]含义相同test 0test用于进行比较和测试文件的属性,您可以在其手册页中了解有关内容。如果没有给出看起来像比较,文件测试或它可以执行的其他操作之一的表达式,它将代替测试该参数是否存在以及非空字符串。无论是01用于测试真正适当的投入,并作为非空字符串测试是成功,while循环循环下去。

您可能想尝试

while false; do
  echo "hello"
done

可能替换falsetrue。或者,也许您想要使用(( ))

while (( 0 )); do
  echo "hello"
done

这与大多数语言一样,其中0表示失败/错误,1表示成功/正确。


1
回复:“当没有给出看起来像比较,文件测试或它可以执行的其他操作之一的表达式时,它只是成功而已”:我认为这不是放置它的好方法。毕竟,[ ](不带参数)和[ "" ](带一个空参数)都不会成功。
ruakh

3
正如@ruakh解释的那样,该语句是错误的:如果未给它提供看起来像比较,文件测试或它可以执行的其他操作之一的表达式,则该语句成功。 任何单一参数测试(方括号内的任何单个参数)被认为是TRUE,如果参数不是一个空字符串,并且两者01不为空字符串。新的Shell程序员经常写if [ 1=2 ]而不是写,if [ 1 = 2 ]并且想知道为什么前者总是正确的。的确如此,因为它是单个参数,并且不是空字符串。
伊恩·艾伦

好点,我已更正。
wingedsubmariner 2013年

10

此处的值0不能用作数字常量,而可以用作字符串。这些测试在产生成功终止状态的效果方面均等效:

[ A ]
[ "XYZ" ]
[ 0 ]

这些将产生失败的终止状态:

[ ]
[ "" ]

有一个非空白的参数,其计算结果为逻辑真。这使您可以执行以下操作:

if [ $UNDER_NUCLEAR_ATTACK ] ; then
  launch-missiles -a $DRY_RUN  # $DRY_RUN set to "-n" during testing
fi

将该变量UNDER_NUCLEAR_ATTACK设置为任何非空白值以表示true,或者将其设置为空或空白以表示false。

我们可以应用!运算符来反转逻辑:

[ ! a ]  # fails: a is nonblank so true; and not true is false.
[ ! ]    # succeeds: blank is false, not blank is true.

要评估数值条件,您必须使用数值测试运算符:

 while [ $A -gt $B ] ; do ...

如果AB包含看起来像十进制整数的字符串,则将它们像数字一样进行比较,如果A大于B,则执行循环。因此,假设这UNDER_NUCLEAR_ATTACK不是一个空白或非空白的字符串型布尔值,而是一个实际上是0(false)或其他值(true)的数字布尔值。在这种情况下,我们将这样编写测试:

 if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...

-1

if / then构造测试命令列表的退出状态是否为0(因为UNIX约定,0表示“成功”),如果是,则执行一个或多个命令。

简而言之,您返回的测试结果为零。

http://www.tldp.org/LDP/abs/html/testconstructs.html


5
是的,但并非出于您似乎想的原因。如果[仅获取一个参数(]当然不包括),则如果参数不为空,则退出,状态为零,否则为非零。因此,例如,[ 1 ]还将返回退出代码0
凯文

-1

对于while循环,将0值视为true,因此while循环的条件为true,因此连续显示无限循环。如果将0替换为1,则为true,因为我们在条件之间写入的任何整数将返回true

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.