【问题标题】:Redirecting tail output into a program将尾部输出重定向到程序中
【发布时间】:2016-04-10 03:47:17
【问题描述】:

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

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

(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 正在打印任何内容吗? -n 关闭打印模式空间,因此该命令的唯一输出将是您使用 p 显式打印的内容。 (我认为...我对 sed 做的不多。)试试cat ~/inputfile | sed -n -r 'some regex' 看看是否打印了任何内容。如果不是,那么,你知道为什么!
  • 在您的前两个示例中,我认为cat 不会被执行。在所有示例中,shell 运行echo(成功),因此它继续执行第二个命令,管道tail | sed。但是tail -f 永远不会退出——它只是等待更多数据出现在~/inputfile 的末尾。 sed 可能正在缓冲输出(或者可能根本没有输出),但直到 tail 退出,sed 也不会完成并退出。在tail | sed 退出之前,cat 不会被执行。 (我认为你根本不需要cat,真的。)~/inputfile 后面还有其他进程吗?
  • @DaveM。是的 sed 正在使用该组合打印单个捕获组。我可以保证它可以工作并且正在打印一些东西。你对 cat 没有被执行是对的,尽管删除它并没有改变任何东西 - 管道仍然不起作用。是的,另一个进程正在附加到 ~/inputfile,我想将该输出的一部分发送到我的程序。
  • @DaveM。我希望通过使用&& cat 能够通过在终端中输入来保留标准输入,但你是对的,它在那里不起作用。如果我把它放在前面,那么它同样会停止执行 tail 命令。
  • 如果您的sed 支持-u(无缓冲)选项,请尝试。在 Debian-8、sed-4.2.2 上为我工作。

标签: linux bash tail


【解决方案1】:

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

stdbuf -i0 -o0 -e0 

比使用 unbuffer 更可取,这对我来说甚至都不起作用。 Dave M 建议使用 sed 相对较新的 -u 似乎也能解决问题。

【讨论】:

    【解决方案2】:

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

    (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 的输出可能被缓冲了一点。您可以尝试使用-u 选项到sed 以使其使用无缓冲输出:

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

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

    【讨论】:

    • 使用 & cat 而不是 && cat 给了我我想要的结果:能够同时将输入输入到程序中并使用键盘与之交互。
    • & cat 表示在后台运行之前的管道(tail | sed),而在前台运行cat——与&&完全不同
    【解决方案3】:

    您可以使用sed 中的i 命令(详见手册页中的命令列表)进行开头插入:

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

    【讨论】:

    • 我不确定你在这里推荐什么,我尝试添加 i 命令但没有额外成功
    猜你喜欢
    • 1970-01-01
    • 2020-10-24
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多