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

Sta*_*ool 4 xargs tail

我想要tail -f /var/log/syslog | grep它带有模式“arpwatch”并通过 jabber 将每一行发送给我自己:xmpp username@jabber.server使用 xargs

tail -f /var/log/syslog | grep arpwatch | xargs sendxmpp username@jabber.server
Run Code Online (Sandbox Code Playgroud)

不工作。

tail /var/log/syslog | grep arpwatch | sendxmpp username@jabber.server

效果很好。

我认为这是对一些根本的东西xargs,并tail -f说我不明白。

ilk*_*chu 5

xargs command尝试为一次命令调用收集尽可能多的输入项(行、词),并且它并不特别关心输入数据的时间。如果tail进程被终止,或者xargs缓冲区被填满,它将使用当时收到的参数运行命令。但是,tail -f通常不会自行完成,并且命令行参数的限制可能很大,因此它似乎根本不起作用。

您可以使用xargs -n1它一次只将一个输入项传递给command,但是您会被xargs使用空格将输入拆分为多个项的事实所打击,因此输入行 offoo 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'
Run Code Online (Sandbox Code Playgroud)

xargs -L 1 也可以,但它仍然会将行拆分为单独的参数,而不是将整行作为一个参数传递。


pLu*_*umo 5

grep可以选择--line-buffered立即输出每一行而不是等待更多输入。

对于xargs,正如@ikkachu 所建议的,您需要用换行符而不是空格分隔。你可以用xargs -L它。

这应该有效:

tail -f /var/log/syslog \
  | grep --line-buffered arpwatch \
  | xargs -L1 sendxmpp username@jabber.server
Run Code Online (Sandbox Code Playgroud)