我想要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
说我不明白。
xargs command
尝试为一次命令调用收集尽可能多的输入项(行、词),并且它并不特别关心输入数据的时间。如果tail
进程被终止,或者xargs
缓冲区被填满,它将使用当时收到的参数运行命令。但是,tail -f
通常不会自行完成,并且命令行参数的限制可能很大,因此它似乎根本不起作用。
您可以使用xargs -n1
它一次只将一个输入项传递给command,但是您会被xargs
使用空格将输入拆分为多个项的事实所打击,因此输入行 offoo 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'
Run Code Online (Sandbox Code Playgroud)
xargs -L 1
也可以,但它仍然会将行拆分为单独的参数,而不是将整行作为一个参数传递。
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)