Take the 2-minute tour ×
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, gitorious.org/irctk –  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

4 Answers 4

up vote 25 down vote accepted

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
2  
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
4  
@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
3  
@sillyMunky Silly Monkey, WaelJ's answer is wrong (sends infinite zeros to stdin). –  P.T. Jul 22 '12 at 18:07
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
2  
He specifically asked for "no busy-waiting or periodic wakeups." –  Rob Jul 12 '12 at 21:54
2  
bash: sleep $((64#1_____)) | program > output & –  dtmilano Jul 13 '12 at 5:24

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

share|improve this answer
    
Haha, that's really a nice approach. :) –  a3nm May 7 at 12:16
    
@a3nm: Thanks : ) Seems sleep infinity also works on BSD and Mac. –  Josh Jul 8 at 20:50

Redirect /dev/zero as standard input!

program < /dev/zero > output &
share|improve this answer
6  
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
1  
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

Your Answer

 
discard

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.