我想知道 while 循环如何评估其循环条件。在手册页中它写道:
而列表-1; 做列表-2;完毕
只要列表 list-1 中的最后一个命令返回退出状态为零,while 命令就会连续执行列表 list-2。
和
列表
列表是由运算符 ;、&、&& 或 || 之一分隔的一个或多个管道的序列,并且可选地以 ;、& 或 之一终止。
和
管道
管道是由一个控制运算符分隔的一个或多个命令的序列 | 或|&。管道的格式是:
Run Code Online (Sandbox Code Playgroud)[time [-p]] [ ! ] command [ [|?|&] command2 ... ]
这意味着:
while <single-command>; do <list>; done;
Run Code Online (Sandbox Code Playgroud)
是有效的语法。只要<single-command>返回,就会执行列表0。如果我像这样运行 while 循环,我会收到(显然)错误:
$while aaa; do echo "foo"; done;
If 'aaa' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf aaa
$while ; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).
$while ""; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,使用一个未初始化的变量baras <single-command>,我遇到了一个无限循环:
$while $bar; do echo "foo"; done;
foo
foo
foo
...
Run Code Online (Sandbox Code Playgroud)
这意味着,bar将参数扩展为空字符串 (?),执行 (?) 并始终返回 0。但是为什么我的第二个错误示例不能等效地工作?有趣的是:
$while "$bar"; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).
Run Code Online (Sandbox Code Playgroud)
不起作用。这相当于我的第三个错误示例。$bar 被扩展为空字符串并且保留未转义的引号。
所以我的问题是:shell(在我的例子中是bash)如何解释
$while $bar; do echo "foo"; done;
Run Code Online (Sandbox Code Playgroud)
命令导致无限循环?
更新:
我发现空命令(什么都不做,返回 0)并不难模拟。null 命令对应于:. 所以非终止 while 循环可以等价地写为:
while :; do echo "foo"; done;
Run Code Online (Sandbox Code Playgroud)
该while指令后面是计算返回代码以确定是否应该循环的命令。如果返回值为 ,则继续执行0。
引用未初始化的变量与将其初始化为“”相同。
由于运行空命令不会导致错误,因此它会返回相应的返回码 ( 0):
$ foo=''
$ $foo
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
这是正常行为,否则每次您按 Enter 键而不输入任何内容时,shell 都会给出错误。
请注意,这与指定 shell 识别为问题的空字符串不同:
$ ''
-bash: : command not found
$ echo $?
127
Run Code Online (Sandbox Code Playgroud)