将尾部输出重定向到程序中

Redirecting tail output into a program

我想使用 tail 作为标准输入向程序发送文本文件中的最新行。

首先,我向程序回显一些每次都相同的输入,然后从输入文件中发送尾部输入,该输入文件应首先通过 sed 处理。以下是我希望运行的命令行。但是程序运行时只接收echo输入,不接收tail输入。

(echo "new" && tail -f ~/inputfile 2> /dev/null | sed -n -r 'some regex' && cat) | ./program

但是,下面的操作完全符合预期,将所有内容打印到终端:

echo "new" && tail -f ~/inputfile 2> /dev/null | sed -n -r 'some regex' && cat

所以我尝试了另一种类型的输出,并且在发布回显文本时再次出现,尾部文本没有出现在任何地方:

(echo "new"  && tail -f ~/inputfile 2> /dev/null | sed -n -r 'some regex') | tee out.txt 

这让我认为这是缓冲问题,但我尝试了 unbuffer 程序和此处的所有其他建议 (https://superuser.com/questions/59497/writing-tail-f-output-to-another-file),但没有结果。尾部输出去哪里了,我怎样才能让它按预期进入我的程序?

可以使用sed中的i命令(详见manpage中的命令列表)在开头插入:

tail -f inputfile | sed -e '1inew file' -e 's/this/that/' | ./program

当我在 sed 命令前添加以下内容时,缓冲问题得到解决:

stdbuf -i0 -o0 -e0 

比使用 unbuffer 更可取,后者甚至对我都不起作用。 Dave M 关于使用 sed 相对较新的 -u 的建议似乎也可以解决问题。

有一件事您可能会感到困惑——|(管道)的优先级高于 &&(连续执行)。所以当你说

(echo "new" && tail -f ~/inputfile 2> /dev/null | sed -n -r 'some regex' && cat) | ./program

相当于

(echo "new" && (tail -f ~/inputfile 2> /dev/null | sed -n -r 'some regex') && cat) | ./program

所以 cat 并没有真正做任何事情,sed 输出可能被缓冲了一点。您可以尝试使用 sed-u 选项来让它使用无缓冲输出:

(echo "new" && (tail -f ~/inputfile 2> /dev/null | sed -n -u -r 'some regex')) | ./program

我相信 sed 的某些版本在输出是终端而不是管道时默认为 -u,因此这可能是您所看到的差异的来源。