I have a program which produces useful information on stdout
but also reads from stdin
. I want to redirect its standard output to a file without providing anything on standard input. So far, so good: I can do:
program > output
and don't do anything in the tty.
However, the problem is I want to do this in the background. If I do:
program > output &
the program will get suspended ("suspended (tty input)").
If I do:
program < /dev/null > output &
the program terminates immediately because it reaches EOF.
It seems that what I need is to pipe into program
something which does not do anything for an indefinite amount of time and does not read stdin
. The following approaches work:
while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
However, this is all very ugly. There has to be an elegant way, using standard Unix utilities, to "do nothing, indefinitely" (to paraphrase man true
). How could I achieve this? (My main criteria for elegance here: no temporary files; no busy-waiting or periodic wakeups; no exotic utilities; as short as possible.)
Best Answer
In shells that support them (ksh, zsh, bash4), you can start
program
as a co-process.ksh
:program > output |&
zsh
,bash
:coproc program > output
That starts
program
in background with its input redirected from apipe
. The other end of the pipe is open to the shell.Three benefits of that approach
program
dies (usewait
to wait for it)program
will terminate (geteof
on its stdin if the shell exits).