+5  A: 

Have you tried File::Tail to handle the actual tailing instead of trying to coerce <STDIN> to do the job?

Or, if that piece does work, in what way is this failing?

Dave Sherohman
No; I've not yet tried it. But I will... I should have known, I suppose. My search on timeout didn't find that.
Jonathan Leffler
How do you do it for a non-file device, like `/dev/ttyUSB0`? I tried File::Tail and it doesn't work on that device, when `tail -f` works fine.
Neil
+1  A: 

The problem is most probably related to output buffering. Have a read if you want a thorough explanation:

http://www.pixelbeat.org/programming/stdio_buffering/

In my case (on RHEL, I wanted tail -n 0 -f file | grep -m 1 pattern to terminate immediately when pattern occurs in the growing file), the proposed LD_PRELOADED library didn't help, neither did plain usage of the unbuffer utility from the Expect package.

But based on a blog post (http://www.smop.co.uk/blog/index.php/2006/06/26/tail-f-and-awk/) I've discovered that redirecting input from tail launched in a subshell did the trick:

grep -m 1 pattern <(tail -n 0 -f file)

This was not as simple, though. While working in an interactive shell, the same command, when run remotely using SSH, still froze as usual:

ssh login@hostname 'grep -m 1 pattern <(tail -n 0 -f file)'

I've discovered that in this case, one must unbuffer tail's output using the unbuffer utility from Expect:

ssh login@hostname 'grep -m 1 pattern <(unbuffer -p tail -n 0 -f file)'

This must not be used on an interactive shell - unbuffer will cause an ioctl(raw): I/O error!

Aleksander Adamowski