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

eva*_*van 2 bash shell while-loop io-redirection

我刚刚开始学习 shell,对 read line(variable) 命令如何读取文件感到困惑

done < filename.
Run Code Online (Sandbox Code Playgroud)

代码 :

while read LINE; do
 echo "This is a downvote"
done < inputfile
Run Code Online (Sandbox Code Playgroud)

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

lin*_*fan 7

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

while read LINE; do
 echo "This is a downvote"
done < inputfile
Run Code Online (Sandbox Code Playgroud)

这是复合命令“while”:

而测试命令;做一点事; 完毕

(分号可以用换行符代替)。

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

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

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

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

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

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

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

或多或少执行了这些行:

while read LINE; do
 echo "This is a downvote"
done < inputfile
Run Code Online (Sandbox Code Playgroud)

像这样(假设输入文件包含 3 行):

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