2

Look at this code:

while read -t 3 line; do
    echo ${line}
done < /opt/data.log

data.log is a fifo. One process is writing to this, and this code should be reading it to show to the user. But I want it to exit when there is no more data in the fifo for 3 seconds.

The problem is it never times out. I write to this fifo, it shows me:

read: 6: Illegal option -t 

What is wrong?

[UPDATE]

Yes, I was using /bin/sh as a shebang which is a symbolic link to dash. I changed it to /bin/bash. but it does not make any benefit. It waits for ever if no one opens the fifo. I want a timeout solution that works when the other end of the fifo has not opened it.

Majid Azimi
  • 3,098
  • Perhaps useful: http://unix.stackexchange.com/questions/10698/timing-out-in-a-shell-script But if you don't have stringent portability requirements like I did, using bash is a lot simpler – Gilles 'SO- stop being evil' Jul 25 '12 at 22:48
  • The timeout isn't happening because the read isn't executing yet. The redirection has to open the FIFO before the loop can start, and the open is blocking. You need a timeout on the redirection operator. I can't think of a good way to do that... – Alan Curry Jul 28 '12 at 05:20

2 Answers2

4

are you using bash? or some other sh? read -t is a kshism (also supported by bash and zsh but not standard)

It works in bash, but not in dash:

$ bash -c 'echo foo | while read -t 3 xxxx ; do echo $xxxx ; done'
foo
$ dash -c 'echo foo | while read -t 3 xxxx ; do echo $xxxx ; done'
dash: 1: read: Illegal option -t
cas
  • 78,579
2

I did find a good way to do this:

exec 5<>/opt/data.log

while read -7 3 line <& 5; do
    echo ${line}
done

I open it for read and write so the script does not block for ever. here is the descriptin: https://stackoverflow.com/a/4875924/654269

Majid Azimi
  • 3,098