为什么重定向到 while 循环不会打印消息?

为什么重定向到 while 循环不会打印消息?

下面是一个用于跟踪文件变化并将内容输出到终端的 shell 代码:

while read LINE
do
  echo $LINE
done < `tail -f /var/log/messages`

它不起作用,为什么?

答案1

不需要 while 循环。您尝试执行两次相同的操作。而且该文件/var/log/messages不再存在于 ubuntu 中。

只需使用:

tail -f /var/log/syslog

跟踪在文本文件末尾添加的新内容。如果在末尾写入了新内容,则会/var/log/syslog将其打印到终端上。

编辑:为什么问题中的命令不起作用:

首先,当然/var/log/messages不存在。但如果存在,则执行反引号之间的命令并由其输出(减去尾随的换行符)替换。因此,的输出tail -f ...将被视为输入重定向的文件名<。您可能想要的内容如下所示(重定向<(...)):

while read LINE; do
  echo $LINE
done < <(tail -f /var/log/messages)

重定向<(...)会创建一个命名管道,命令会从其中的一端tail -f写入内容。循环会从另一端while逐行读取内容。命名管道的行为类似于常规文件。它只是两个命令之间的连接部分。顺便说一句,它的|作用完全相同,但这些管道没有命名,它们是默认通道:0 -> stdin、1 -> stdout 和 2 -> stderr。

来自bash手册页:

 Process substitution is supported on systems that support named pipes (FIFOs) or the 
 /dev/fd method of naming open files. It takes the form of <(list) or >(list).  

答案2

通常的可移植方式是:

tail -f /var/log/messages | while read LINE
do
  echo $LINE
done

@chaos 的答案是使用进程替换语法,该语法仅在高级 shell (例如zsh和)中找到bash。 如果您需要在另一台计算机上运行脚本,则不应依赖它们的功能。

当然,我假设你想放入比echo $LINE循环更复杂的东西。

相关内容