在以下 BASH 脚本代码中:
while read -r line
do
if [some_condition]; then
do_thing1
do_thing2
continue
fi
done < $SOME_VAR
最后一行的含义是什么?具体来说,$SOME_VAR 的值正在做什么?
答案1
是<
输入重定向运算符,$SOME_VAR
可能包含文件名。它们一起导致循环从文件中读取行。
答案2
<
是 shell 间接运算符。它获取提供的文件,并将其用作前面命令的标准输入。该命令大致类似于:
cat $SOME_VAR | while read -r line; do
if stuff; then
consequence
else
otherstuff
fi
done
如果SOME_VAR
没有分配给当前工作目录中的文件(或文件的完整路径),shell 将抛出错误No such file or directory
。
答案3
其他两个答案已经涵盖了它的大部分方面。我想补充一点,要理解这种语法,您应该将 解释while ... done
为单个但复杂的语句,并将$SOME_VAR
该语句作为 提供给该语句stdin
。每当需要读取时就会消耗它stdin
。在这种情况下的read
声明。实际上和标准语法没有什么区别cmd <in >out
。
答案4
简而言之,<
重定向文件在符号右侧指定到您正在执行的任何命令或命令组的流<
中。stdin
这while read -r line; do...done < input.txt
是读取文件的标准方法逐行。当然,$SOME_VAR
不一定是文本文件 - 可以是命名管道等 - 这是通常的方法,用于避免 shell 中分词的问题。
通常 shell 脚本新手认为他们可以做类似的事情for line in $(cat file.txt)
,但如果每行有多个用空格分隔的单词,for 循环将处理每个单词而不是每行。像这样的东西:
$ for i in $(cat input.txt); do echo "$i" ; done
one
two
three
four
这不好。相比之下,while 循环可以让您毫无问题地处理整行。
$ while read -r line; do echo "$line" ;done < input.txt
one two
three four
您可能想知道为什么不直接使用cat | while read -r line...
,但这是额外的过程并且对猫的无用利用。
重定向到循环的标准输入流也可以通过其他方式完成。如果您使用bash
support <<<
,您可以将文本的字符串文字发送到 while 循环。
while read -r line;do
# do something with line
done <<< "Hello World"
一个多余的例子?是的,但证明了这样的语法更多的是关于将输入重定向到 while 循环。
也可以看看: