如果我有一个正在运行的进程,例如tail -F watch.txt
,我想stdout
从该正在运行的进程中捕获并将其通过管道传输到标准输出上的另一个命令,该怎么做?
这是一个正在运行的进程的示例。
$ tail -F watch.txt
foo
bar
baz
假设我想捕获stdout
并将每个字符串写入一个新文件或使用另一个命令处理每个字符串。例如,有一个terminal-notifier
(特定于 mac 的)命令,它接受一条消息terminal-notifier --message "$STDOUT_FROM_TAIL"
。
对于 unix 中已经存在的东西来说这可能吗?
答案1
假设您可以重新启动程序并将其放入管道中,然后您可以将其通过管道传输到xargs
,但需要注意以下事项:
- 您想要一次运行一行命令 (-n 1)
- 您想将输出放入参数 (-i)
- 您可能希望消息在
tail
报告后立即运行,因此您需要tail
需要行缓冲。
根据您安装的内容:
stdbuf -o 0 tail -f FILE | xargs -i -n 1 terminal-notifier --message "{}"
unbuffer tail -f FILE | xargs " "
我看到一个tailf
支持-l
(行缓冲)选项的版本。
您还可以tail -f
用 Perl 进行模拟。
您可以用shell 中xargs
特制的循环来替换(即使它非常标准且普遍存在) (它是for
不是虽然看起来很简单;它类似于处理带空格的文件名循环中)。
如果无法重新启动程序,则需要拦截其stdout。这是堆栈溢出答案关于那个。其他实用程序和脚本,例如重定向被描述这里;不过我不知道它们与 MacOS 的兼容性。
进一步修改
可以使用 sed 或 cut 等实用程序正常解析输出:
取消缓冲尾部-f文件| grep 动物 | sed -e 's/动物 (.*) gear/\1/' | xargs ...
这样我们就会:
Output by tail output by grep output by sed
correct horse battery staple
animal rhino gear animal rhino gear rhino
llama is animal llama is animal llama is animal
llama peruvian
animal ant gearbox animal ant gearbox antbox
(可以使用--line-buffered
选项)grep