1

Why does tail -f not play well with xargs?

This command works as expected, I see a block of text:

tail /var/log/auth.log|xargs echo

But this command shows me nothing:

tail -f /var/log/auth.log|xargs echo

Both tail and tail -f have output. One might think it is line terminators, but setting both to null did not work:

tail -z -f /var/log/auth.log|xargs -0 echo

jcalfee314
  • 4,642
  • 8
  • 43
  • 75

1 Answers1

3

Because tail -f doesn't terminate; it is still waiting for new lines to be added. And xargs (unless you use -L or similar) waits until it has "enough" arguments to make it worthwhile executing the command line.

If your intention was to execute the command once for each line, use xargs -L1. See man xargs for details:

   -L max-lines
         Use at most max-lines nonblank input lines per command line.
         Trailing blanks cause an input line to be logically continued
         on the next input line.  Implies `-x`.

Watch out for the "trailing blanks" behaviour. You can avoid that by using -I instead of -L1 and specifying an explicit replacement argument:

tail -f /var/log/auth.log | xargs -I {} echo {}
rici
  • 234,347
  • 28
  • 237
  • 341
  • Any idea why the -f in tail breaks this command? `tail -fz /var/log/auth.log | egrep -o failure |xargs -L1 echo \>` (with -f there is no output). – jcalfee314 May 12 '17 at 16:40
  • 1
    @jcalfee314: It's a very similar problem. `egrep` buffers its output so it doesn't write anything until it has "enough" to write (usually several thousand characters). You can use `stdbuf` to attempt to force `grep` to line-buffer. There are many duplicate questions on SO. – rici May 12 '17 at 16:46
  • @jcalfee314: Here's the first one I found with an SO search: http://stackoverflow.com/questions/36822898/why-cant-i-filter-tails-output-multiple-times-through-pipes/ – rici May 12 '17 at 16:48