while 循环中的读取行如何工作

How read line in while loop works

我刚开始学习 shell 并且对读取行(变量)命令如何读取

中的文件感到困惑
done < filename.

代码:

while read LINE; do
 echo "This is a downvote"
done < inputfile

我的假设是当 while 运行行变量为空并且它应该为 false 并且 while 循环退出但它没有。 read 是否在循环中检查文件,我知道输入重定向命令已传递给文件。有人可以解释一下它是如何工作的吗?

read LINEreturns成功(退出代码0)不管该行是否为空它returns'false'(非零退出代码)仅当到达文件末尾或发生另一个错误时(有关详细信息,请参阅下一节)。

文档

来自help read

Exit Status:
The return code is zero, unless end-of-file is encountered, read times out (in which case it's greater than 128), a variable assignment error occurs, or an invalid file descriptor is supplied as the argument to -u.

让我们分析一下这个片段:

while read LINE; do
 echo "This is a downvote"
done < inputfile

这是复合命令“while”:

同时测试命令;做一点事;完成

(分号可以换行)

首先,TESTCOMMAND 是一个完整的命令,可能由很多单词组成——这就是为什么它以分号或换行符结尾的原因。例如,TESTCOMMAND 可以是“tail file.txt | grep bye”:这是很多词,实际上两个命令是 运行,中间有一个竖线。

对于每次迭代,TESTCOMMAND 都是 运行,如果成功,则执行“do”和“done”之间的命令(SOMETHING 部分)。如果 TESTCOMMAND 失败,则退出循环。

现在,让我们看看 TESTCOMMAND 为“读取 LINE”时的情况。在执行之前,“read”和“LINE”这两个词只是简单地表示它们是什么:两个词,第一个是“read”,第二个是“LINE”。第一个词将是要执行的命令的名称;所有其他人将成为命令的论据。所以,你看,“LINE”是一个没有特殊含义的词,它不是一个变量——它的内容甚至没有被评估(为了在命令执行之前评估它, 我们会写 "$LINE").

然后执行命令“读取”。正是该命令“read”将其参数“LINE”解释为要写入的变量名。其他命令可以将该词(“LINE”)解释为文件名、文本词或任何他们想要的东西。

该片段的最后一行“done < inputfile”表示该命令必须重定向其(标准)输入:该命令不会读取标准输入(在许多情况下是控制台),但是指定的文件(在本例中为“inputfile”)。

重定向适用于什么命令?它是 while 命令及其所有“子项”。不要因为重定向符号“<”似乎与关键字“while”相距甚远而感到困惑。 shell看到“while”,就知道后面还有对应的“done”。

---评论请求后更新---

如果这些行或多或少执行:

while read LINE; do
 echo "This is a downvote"
done < inputfile

是这样的,假设输入文件包含 3 行:

  1. shell 找到“while”并解析它直到“done”
  2. 找到重定向,因此重定向标准输入
  3. 循环开始
  4. “read LINE”被执行,变量FILE被填充为从inputfile读取的第一行,读取命令returns“成功”
  5. ...所以正文“echo ...”被执行
  6. “完成”关键字重新开始循环
  7. “read LINE”和“echo ...”被执行了两次
  8. 当尝试从输入文件中读取第四行时,读取命令失败(文件结尾)并且 returns“失败”
  9. “while”循环中断(跳转到结束)
  10. ...最后说要重置标准输入
  11. 脚本的其余部分继续执行。