"while :;" 是什么意思 意思?

sha*_*ant 28 bash shell-script

我知道什么是while循环。但是,我只看到它适用于:

while [condition]
while ![condition]
while TRUE (infinite loop)
Run Code Online (Sandbox Code Playgroud)

后面的语句while必须是TRUEor FALSE

有一个名为:. 它被描述为一个什么都不做的虚拟命令,但我不知道它在这里是否相同,即使它可以是TRUEFALSE。也许它是不同的东西,但什么?

Sté*_*las 51

语法是:

while
  first list of commands
do
  second list of commands
done
Run Code Online (Sandbox Code Playgroud)

只要第一个命令列表(因此该列表中的最后一次运行)成功,它就会在循环中运行第二个命令列表。

第一个命令列表中,您可以使用该[命令进行各种测试,或者您可以使用:不执行任何操作并返回成功的null 命令或任何其他命令。

while :; do cmd; done
Run Code Online (Sandbox Code Playgroud)

cmd永远运行一遍又一遍,:总是会返回成功。这就是永远的循环。您可以改用该true命令使其更清晰:

while true; do cmd; done
Run Code Online (Sandbox Code Playgroud)

用喜欢的人::总是内置,而true不是(很久以前,大部分炮弹都true时下内置)¹。

您可能会看到的其他变体:

while [ 1 ];  do cmd; done
Run Code Online (Sandbox Code Playgroud)

上面,我们调用[命令来测试“1”字符串是否为非空(所以也总是如此)

while ((1)); do cmd; done
Run Code Online (Sandbox Code Playgroud)

使用 Korn/bash/zsh((...))语法来模仿while(1) { ...; }C 的语法。

或更令人费解的像until false; do cmd; doneuntil ! true...

这些有时别名如下:

alias forever='while :; do'
Run Code Online (Sandbox Code Playgroud)

因此,您可以执行以下操作:

forever cmd; done
Run Code Online (Sandbox Code Playgroud)

很少有人意识到条件是一个命令列表。例如,你看到人们在写:

while :; do
  cmd1
  cmd2 || break
  cmd3
done
Run Code Online (Sandbox Code Playgroud)

当他们可以写:

while
  cmd1
  cmd2
do
  cmd3
done
Run Code Online (Sandbox Code Playgroud)

将它作为一个列表确实很有意义,因为您经常想做一些诸如while cmd1 && cmd2; do...; done命令列表之类的事情。

在任何情况下,请注意,[是像任何其他的命令(虽然它内置的现代类似Bourne外壳),它并没有被在单独使用if/ while/until条件列表,这些条件列表没有比任何其他命令更多地使用该命令。


¹:也更短并接受参数(它忽略)。如果传递任何参数,则trueor的行为false是未指定的。例如,可以这样做:

while : you wait; do
  something
done
Run Code Online (Sandbox Code Playgroud)

但是,以下行为:

until false is true; do
  something
done
Run Code Online (Sandbox Code Playgroud)

未指定(尽管它可以在大多数 shell/false实现中工作)。


fro*_*utz 12

while :是一个无限循环。:什么都不做(成功)。

所以如果你想让你的 shell 永远挂起什么都不做,你可以把它写成

while :
do
    :
done
Run Code Online (Sandbox Code Playgroud)

或者在一行中使用;而不是换行符:while :; do :; done

while :如果您想在没有附加特殊条件的情况下重复执行某事,则通常使用。您可以在循环中使用continue,break语句来控制它或将条件像do ... while构造一样移动到循环的末尾。


ilk*_*chu 12

但是,while 之后的语句必须为 TRUE 或 FALSE。

不,条件部分中的命令可以是任何命令(*)所有shell 命令都有一些返回值,并且while循环(以及if条件)将零的返回值视为“真”,将所有其他返回值视为“假”。(* 或多个命令的列表,最后一个计数)

至于:Bash 的手册清楚地说明了它的返回状态是什么:

: [arguments]
除了扩展参数和执行重定向之外,什么都不做。返回状态为零。

help内置更是明确:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
Run Code Online (Sandbox Code Playgroud)