Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

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.)

share|improve this question
Try su -c 'program | output &' user. I am about to ask a similar question with creating background jobs as an acceptable method for handling a "service/daemon." I also noticed that I could not redirect STDERR without also redirecting STDOUT. The solution where programA sends STDOUT to STDIN of programB, then redirects STDERR to a log file: programA 2> /var/log/programA.log | programB 2> /var/log/programB.log 1> /dev/null – mbrownnyc Jul 12 '12 at 19:12
maybe... su -c 'while true; do true; done | cat > ~/output &' user? – mbrownnyc Jul 12 '12 at 19:39
what kind of program is that? – João Portela Jul 13 '12 at 9:38
João Portela: This is a program I wrote, – a3nm Jul 13 '12 at 12:37
Why not simply add a switch to that program you wrote? Also, I assume that if you close stdin with 1<&- it will exit your program? – w00t Jul 19 '12 at 19:10

8 Answers 8

up vote 1 down vote accepted

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 a pipe. The other end of the pipe is open to the shell.

Three benefits of that approach

  • no extra process
  • you can exit the script when program dies (use wait to wait for it)
  • program will terminate (get eof on its stdin if the shell exits).
share|improve this answer
That seems to work and looks like a great idea! (To be fair, I had asked for something to pipe to my command, not for a shell feature, but this was just the XY problem at play.) I'm considering accepting this answer instead of @P.T.'s one. – a3nm Aug 14 at 21:26
@a3nm, tail -f /dev/null is not ideal as it does a read every second on /dev/null (current versions of GNU tail on Linux using inotify there is actually a bug). sleep inf or its more portable equivalent sleep 2147483647 are better approaches for a command that sits there doing nothing IMO (note that sleep is built in a few shells like ksh93 or mksh). – Stéphane Chazelas Aug 15 at 21:03
very interesting, thanks! – a3nm Aug 23 at 17:55

On Linux, you can do:

read x < /dev/fd/1 | program > output

On Linux, opening /dev/fd/x where x is a file descriptor to the writing end of a pipe, gets you the reading end of the pipe, so here the same as on the stdin of program. So basically, read will never return, because the only thing that may write to that pipe is itself, and read doesn't output anything.

It will also work on FreeBSD or Solaris, but for another reason. There, opening /dev/fd/1 gets you the same resource as open on fd 1 as you'd expect and as most systems except Linux do, so the writing end of the pipe. However, on FreeBSD and Solaris, pipes are bidirectional. So as long as program doesn't write to its stdin (no application does), read will get nothing to read from that direction of the pipe.

On systems where pipes are not bidirectional, read will probably fail with an error when attempting to read from a write-only file descriptor. Also note that not all systems have /dev/fd/x.

share|improve this answer
Very nice! In fact my tests you don't need the x with bash; further with zsh you can just do read and it works (though I don't understand why!). Is this trick Linux-specific, or does it work on all *nix systems? – a3nm Aug 11 at 22:45
@a3nm, if you do read alone, it will read from stdin. So if it's the terminal, it will read what you type until you press enter. – Stéphane Chazelas Aug 12 at 7:10
sure, I understand what read does. What I don't understand is why reading from the terminal with read in a backgrounded process is blocking with bash but not with zsh. – a3nm Aug 14 at 21:19
@a3nm, I'm not sure what you mean. What do you mean by you can just do read and it works? – Stéphane Chazelas Aug 15 at 20:51
I'm saying that with zsh you can just do read | program > output and it works in the same way as what you suggested. (And I don't get why.) – a3nm Aug 23 at 17:56

Here's another suggestion using standard Unix utilities, to "do nothing, indefinitely".

sh -c 'kill -STOP $$' | program > output

This fires up a shell that is immediately sent SIGSTOP, which suspends the process. This is used as "input" to your program. The complement of SIGSTOP is SIGCONT, i.e. if you know the shell has PID 12345 you can kill -CONT 12345 to make it continue.

share|improve this answer

You can create a binary that does just that with:

$ echo 'int main(){ pause(); }' > pause.c; make pause
share|improve this answer

sleep infinity is the clearest solution I know of.

You can use infinity because sleep accepts a floating point number*, which may be decimal, hexadecimal, infinity, or NaN, according to man strtod.

* This isn't part of the POSIX standard, so isn't as portable as tail -f /dev/null. However, it is supported in GNU coreutils (Linux) and BSD (used on Mac) (apparently not supported on newer versions of Mac — see comments).

share|improve this answer
Haha, that's really a nice approach. :) – a3nm May 7 '14 at 12:16
@a3nm: Thanks : ) Seems sleep infinity also works on BSD and Mac. – Zaz Jul 8 '14 at 20:50
What kind of resources does a infinitely sleeping process take? Just RAM? – CMCDragonkai May 29 at 6:37
@CMCDragonkai: Yes, and a negligible amount of CPU. I don't know much about how kernels deal with processes, but certain operations may take longer, e.g. counting the number of current processes. There are very few circumstances where this would actually affect you, though. – Zaz May 30 at 23:37
sleep infinity doesn't work for me on Mac OS X 10.9. It just returns after a few microseconds. – Quinn Comendant Aug 9 at 0:05

Redirect /dev/zero as standard input!

program < /dev/zero > output &
share|improve this answer
This would give his program an infinite number of zero-bytes... which, sadly, would make it busy-loop. – Jander Jul 12 '12 at 23:51
This is not true jander, /dev/zero will never close, holding the pipe chain open. However, poster says he doesn't take in stdin, so no zeros will ever be transferred to program. This is not a busy loop at all, it is a pure wait. – sillyMunky Jul 22 '12 at 17:38
sorry, OP does use stdin, so this will wipe out his input and will be drawing from /dev/zero. I should read twice next time! If OP wasn't using stdin, this would be the most elegant solution I've seen, and would not be a busy wait. – sillyMunky Jul 22 '12 at 17:46
sleep 2147483647 | program > output &

Yes, 2^31-1 is a finite number, and it won't run forever, but I'll give you $1000 when the sleep finally times out. (Hint: one of us will be dead by then.)

  • no temporary files; check.
  • no busy-waiting or periodic wakeups; check
  • no exotic utilities; check.
  • as short as possible. Okay, it could be shorter.
share|improve this answer
or while true; do sleep 86400; done | program > output & – James Youngman Jul 12 '12 at 21:52
He specifically asked for "no busy-waiting or periodic wakeups." – Rob Jul 12 '12 at 21:54
bash: sleep $((64#1_____)) | program > output & – dtmilano Jul 13 '12 at 5:24

I don't think you're going to get any more elegant than the

tail -f /dev/null

that you already suggested (assuming this uses inotify internally, there should be no polling or wakeups, so other than being odd looking, it should be sufficient).

You need a utility that will run indefinitely, will keep its stdout open, but won't actually write anything to stdout, and won't exit when its stdin is closed. Something like yes actually writes to stdout. cat will exit when its stdin is closed (or whatever you re-direct into it is done). I think sleep 1000000000d might work, but the tail is clearly better. My Debian box has a tailf that shortens command slightly.

Taking a different tack, how about running the program under screen?

share|improve this answer
I like the tail -f /dev/null approach the best and find it elegant enough as well, since the command usage matches the intended purpose quite closely. – jw013 Jul 12 '12 at 19:40
From strace tail -f /dev/null it seems that tail uses inotify and that wakeups occur in silly cases like sudo touch /dev/null. It's sad that there seems to be no better solution... I wonder which would be the right syscall to use to implement a better solution. – a3nm Jul 12 '12 at 19:59
@a3nm The syscall would be pause, but it isn't exposed directly to a shell interface. – Gilles Jul 12 '12 at 22:25
P.T.: I know about screen, but this is to run multiple occurrences of the program from a shell script for testing purposes, so using screen is a bit overkill. – a3nm Jul 20 '12 at 12:19
@sillyMunky Silly Monkey, WaelJ's answer is wrong (sends infinite zeros to stdin). – P.T. Jul 22 '12 at 18:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.