1

I'm using locate(1) from GNU findutils for a little task and it seems as if it buffers its output. I am piping the output of locate to another task that will process the lines as locate finds them. Since locate might take a long time to run, I thought that locate would print out the files as they were found, but it seems that locate is buffering the output.

If I run locate on a TTY, it prints out the first match immediately, and uses maybe 10 seconds to find the rest of the matches.

If, instead I run locate but pipe to cat, I see nothing until the entire command completes.

It seems that locate buffers the output, and has no way of turning it off.

What I want to achieve is to locate some files, and run a command immediately after finding it by piping the output.

locate something | xargs -n 1 do_something

But what happens is that xargs and hence do_something aren't invoked until find completes.

mogsie
  • 221
  • Since you appear to be using find (rather than locate, as suggested by your title) you should be able to use its -exec action to do_something without requiring a pipe to xargs – steeldriver Sep 29 '16 at 11:46
  • Gah, I was actually using locate, not find. Sorry about the confusion. Yes, for find -exec would be the best alternative. – mogsie Sep 29 '16 at 12:53

2 Answers2

1

Of course I found the answer immediately after posting, in a post suggested by stackexchange when posting.

unbuffer (from expect) solves this.

unbuffer locate something | xargs -n 1 do_something

runs the commands as fast as locate can find them.

mogsie
  • 221
1

locate buffers the STDOUT stream, you need to make the STDOUT of locate unbuffered (or line buffered).

If you are on a GNU system, you can use stdbuf (comes with GNU coreutils).

To make the STDOUT of locate unbuffered:

stdbuf -o0 locate something | ...

Line buffered:

stdbuf -oL locate something | ...

Check man stdbuf to get more idea.

heemayl
  • 56,300