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
  • 4
  • 6
  • 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
  • 4
  • 6
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
  • 54,820
  • 8
  • 124
  • 141