我想使用 bash、tail 并使用不同的文件描述符逐行读取文件。所有指南都使用此方法:
方法一:
echo 1111111 > z.txt
exec {newFD}< <(tail -f -c +0 "z.txt")
while IFS= read -r LINE0 <&${newFD}
do
printf '%s' "$LINE0"
done
但这个方法也有效:
方法2:
echo 1111111 > z.txt
while IFS= read -r LINE0 <&${newFD}
do
printf '%s' "$LINE0"
done {newFD}< <(tail -f -c +0 "z.txt")
使用第二种方法有没有问题?
为什么我不需要exec
第二种方法?谢谢。
{newFD} 自动给了我一个免费的文件描述符:自 bash 4.1+ 起可用的功能 (2009-12-31) {varname} 样式自动文件描述符分配
答案1
你不知道。在这两种情况下,您都将获得分配并存储在 中的新文件描述符newFD
,从进程替换中读取。没有功能上的区别。两者之间的错误行为可能略有不同,但在本例中应该不明显。
方法 1 可能对 fd 的生命周期更加透明(在任何情况下,它的范围不仅仅限于 while 循环),并且使源更接近它的使用位置。为了清楚起见,我可能更愿意这样写,但实际上没有区别。无论哪种方式,文件描述符都需要随后关闭。
您可以用您喜欢的任何样式来编写此内容,两者都可以。
请注意,这while read
并不是打开文件描述符:任何命令都存在的普通 shell 重定向操作正在发生,以while
或exec
作为命令。循环while
被视为单个复合命令,并在调用 shell 内运行。所有可以附加到命令的常见内容也可以与 while 循环一起使用。
有一些重定向标准 IO 流(或另一个已打开的 FD)时重定向的特殊行为exec
:它将永久操纵当前 shell 的环境,而不仅仅是运行实际命令的子 shell 的环境。但是,这不适用于这种情况{newFD}< ...
。
当像这样动态分配新的 FD 时,FD 总是分配在父级中,而不是子级中,否则该变量将毫无用处。这意味着任何命令将起作用,甚至
: <{newFD} <(...)
做同样的事情exec {newFD}< <(...)
。