![为什么 xargs 不能与 tail -f 一起使用?](https://linux22.com/image/144837/%E4%B8%BA%E4%BB%80%E4%B9%88%20xargs%20%E4%B8%8D%E8%83%BD%E4%B8%8E%20tail%20-f%20%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%EF%BC%9F.png)
我希望tail -f /var/log/syslog | grep
它具有模式“arpwatch”,并通过 jabber 将每一行发送给自己:使用 xargsxmpp [email protected]
tail -f /var/log/syslog | grep arpwatch | xargs sendxmpp [email protected]
不工作。
但tail /var/log/syslog | grep arpwatch | sendxmpp [email protected]
效果很好。
我认为这是一些我不明白的基本xargs
问题tail -f
。
答案1
xargs command
尝试在一次调用中收集尽可能多的输入项(行、单词)命令,并且它并不特别关心输入数据的时间。如果tail
进程被杀死,或者xargs
缓冲区被填满,它将运行命令以及当时收到的论点。但是,tail -f
通常不会自行完成,并且命令行参数的限制可能很大,因此看起来它根本不起作用。
您可以让它xargs -n1
一次只传递一个输入项命令,但是您会发现xargs
使用空格将输入拆分为项目,因此输入行foo bar
会导致命令运行两次。
使用 GNU xargs,xargs -n1 -d '\n'
应该做你想做的事:运行命令每个输入行一次,整行作为单个参数传递。
尝试使用和不使用-d
and-n
并记下输出时序:
$ ( echo "123 456"; sleep 1; echo foo; sleep 1; echo doo ) | xargs -d '\n' -n1 printf ':%s\n'
xargs -L 1
也可以,但它仍然会将行拆分为单独的参数,而不是将整行作为一个参数传递。
答案2
grep
可以选择--line-buffered
立即输出每一行,而不是等待更多输入。
对于xargs
,按照 @ikkachu 的建议,您需要用换行符而不是空格分隔。你可以用xargs -L
它。
这应该有效:
tail -f /var/log/syslog \
| grep --line-buffered arpwatch \
| xargs -L1 sendxmpp [email protected]