为什么 xargs 不能与 tail -f 一起使用?

为什么 xargs 不能与 tail -f 一起使用?

我希望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'应该做你想做的事:运行命令每个输入行一次,整行作为单个参数传递。

尝试使用和不使用-dand-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]

相关内容