Je veux tail -f /var/log/syslog | grep
avec le motif "arpwatch" et envoyez-moi chaque ligne via jabber :xmpp [email protected]
en utilisant xargs
tail -f /var/log/syslog | grep arpwatch | xargs sendxmpp [email protected]
ne fonctionne pas.
mais tail /var/log/syslog | grep arpwatch | sendxmpp [email protected]
fonctionne bien.
Je pense que c'est quelque chose de fondamental à propos de xargs
et tail -f
que je ne comprends pas.
Réponse acceptée :
xargs command
essaie de collecter autant d'éléments d'entrée (lignes, mots) que possible pour une invocation de la commande , et il ne se soucie pas particulièrement de la synchronisation des données d'entrée. Si la tail
le processus est tué, ou xargs
s le tampon est rempli, il exécutera la commande avec les arguments qu'il a alors reçus. Cependant, tail -f
ne se termine généralement pas tout seul, et la limite des arguments de ligne de commande peut être importante, il semble donc que cela ne fonctionne pas du tout.
Vous pouvez utiliser xargs -n1
pour qu'il ne transmette qu'un seul élément d'entrée à la fois à la commande , mais vous serez frappé par le fait que xargs
utilise des espaces pour diviser l'entrée en éléments, donc une ligne d'entrée de foo bar
entraînerait l'exécution de la commande deux fois.
Avec GNU xargs, xargs -n1 -d '\n'
devrait faire ce que vous voulez :exécutez la commande une fois pour chaque ligne d'entrée, la ligne complète étant transmise en tant qu'argument unique.
Essayez, par ex. avec et sans le -d
et -n
et notez le timing de sortie :
$ ( echo "123 456"; sleep 1; echo foo; sleep 1; echo doo ) | xargs -d '\n' -n1 printf ':%s\n'
xargs -L 1
fonctionnerait également, mais cela diviserait toujours la ligne pour séparer les arguments, au lieu de passer la ligne entière comme un seul argument.