How to do nothing forever in an elegant way?
Solution 1
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 (usewait
to wait for it) -
program
will terminate (geteof
on its stdin if the shell exits).
Solution 2
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
?
Solution 3
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).
Solution 4
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.
Solution 5
You can create a binary that does just that with:
$ echo 'int main(){ pause(); }' > pause.c; make pause
Related videos on Youtube
Budda
Updated on September 18, 2022Comments
-
Budda over 1 year
Request Execute is failed if one of fields to be mapped has DateTime field and corresponding value in DB has '0000-00-00' or '0001-01-01'. The following error is returned
Unable to convert MySQL date/time value to System.DateTime
Is there any possibility to fetch such value?
I've tried to specify the 'DateTime?' value as property type - it doesn't help too (actually, I didn't expect that to be helpful).
P.S. I use MySql 5.1
-
Admin almost 12 yearsTry
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 redirectSTDERR
without also redirectingSTDOUT
. The solution where programA sendsSTDOUT
toSTDIN
of programB, then redirectsSTDERR
to a log file:programA 2> /var/log/programA.log | programB 2> /var/log/programB.log 1> /dev/null
-
Admin almost 12 yearsmaybe...
su -c 'while true; do true; done | cat > ~/output &' user
? -
Admin almost 12 yearswhat kind of program is that?
-
Admin almost 12 yearsJoão Portela: This is a program I wrote, gitorious.org/irctk
-
Admin almost 12 yearsWhy 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? -
Admin almost 12 yearsw00t: Did you mean "<&-"? Indeed, it makes the program terminate. Adding a switch is not a very elegant solution, because it feels like there should be a sensible way to reach the desired behavior by giving the adequate input to the program.
-
-
jw013 almost 12 yearsI 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. -
Shruti almost 12 yearsFrom
strace tail -f /dev/null
it seems thattail
usesinotify
and that wakeups occur in silly cases likesudo 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. -
Gilles 'SO- stop being evil' almost 12 years@a3nm The syscall would be
pause
, but it isn't exposed directly to a shell interface. -
Jander almost 12 yearsThis would give his program an infinite number of zero-bytes... which, sadly, would make it busy-loop.
-
Diego Torres Milano almost 12 yearsbash: sleep $((64#1_____)) | program > output &
-
Shruti almost 12 yearsP.T.: I know about
screen
, but this is to run multiple occurrences of the program from a shell script for testing purposes, so usingscreen
is a bit overkill. -
sillyMunky almost 12 yearsThis 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 almost 12 yearsI don't know why this answer is so popular. It is not as good as Waelj's by any measure except a few chars shorter. Its more resource intensive and its not clear how it works in the absence of inotify, which is non-standard.
-
sillyMunky almost 12 yearssorry, 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.
-
Michael Nelson almost 12 years@sillyMunky Silly Monkey, WaelJ's answer is wrong (sends infinite zeros to stdin).
-
Shruti about 10 yearsHaha, that's really a nice approach. :)
-
Zaz almost 10 years@a3nm: Thanks : ) Seems
sleep infinity
also works on BSD and Mac. -
CMCDragonkai almost 9 yearsWhat kind of resources does a infinitely sleeping process take? Just RAM?
-
Zaz almost 9 years@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.
-
Quinn Comendant almost 9 years
sleep infinity
doesn't work for me on Mac OS X 10.9. It just returns after a few microseconds. -
Zaz almost 9 years@QuinnComendant: Really? Does it give you an error message? Does it behave differently to, e.g.
sleep some-random-text
? -
Quinn Comendant almost 9 years
sleep infinity
andsleep asdfasdf
both return immediately, with an exit code of 0, and no message. -
Zaz almost 9 yearsHmm, odd. I'm not sure why that's happening.
-
Shruti almost 9 yearsVery nice! In fact my tests you don't need the
x
with bash; further with zsh you can just doread
and it works (though I don't understand why!). Is this trick Linux-specific, or does it work on all *nix systems? -
Stéphane Chazelas almost 9 years@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. -
Shruti almost 9 yearssure, 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.
-
Shruti almost 9 yearsThat 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.
-
Stéphane Chazelas almost 9 years@a3nm, I'm not sure what you mean. What do you mean by you can just do
read
and it works? -
Stéphane Chazelas almost 9 years@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 equivalentsleep 2147483647
are better approaches for a command that sits there doing nothing IMO (note thatsleep
is built in a few shells likeksh93
ormksh
). -
Shruti over 8 yearsI'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.) -
Adam Mackler over 8 yearsWarning: I tried putting this into a shell script on FreeBSD. Sending SIGINT to the script fails to interrupt since
tail
keeps running, and sending SIGTERM (or SIGKILL) terminates (or kills) the shell script buttail
keeps running in the background. -
yvanscher over 8 yearsany ideas about why sleep infinity returns? I'm on OS X 10.10.5 and have the same thing happening, just using sleep SUPER_BIG# for now. I liked the elegance of the infinity.
-
Zaz over 8 years@yvanscher: I'm afraid I don't have a Mac to test it, but I guess Macs don't have true IEEE floating point support for console commands. Does
sleep 1e99
work for you? (thats 10^91 years) -
yvanscher over 8 years@Zaz: I did something of the like. I can rest easy knowing my script won't exit until the end of the life of this universe. Thanks for your help.
-
Stéphane Chazelas over 7 yearsDoesn't work on FreeBSD 11 either nor with the sleep builtin of mksh. Works on Solaris 11 or with the ksh93 sleep builtin.
-
agc almost 7 yearsThat sleeps for 68 years, this sleeps for 98 centuries:
sleep 2147483647d
... -
nh2 over 6 yearsThis answer claims that
sleep infinity
waits for 24 days at max; who's right? -
Zaz over 6 years@nh2: Excellent comment! Try
strace sleep infinity
orstrace sleep 9999999999
, you'll see that the last system call isnanosleep({2073600, 999999999}
, so the sleep utility is limited to 24 days = 2073600 seconds, no matter what you do. -
nh2 over 6 years@Zaz I have investigated the issue in detail now. It turns out that you were initially correct! The
sleep
utility is not limited to 24 days; it is just the first syscall that sleeps for 24 days, and afterwards it will do more such syscalls. See my comment here: stackoverflow.com/questions/2935183/… -
jdf over 5 yearsstackoverflow.com/questions/2935183/… is worth a read for why to prefer sleep loop over tailing /dev/null
-
Marcello Romani about 3 years
coproc
doesn't seem to be part of Mac OS X, whiletail -f /dev/null
works on Linux and Mac OS X. My version isGNU bash, version 3.2.57(1)-release (arm64-apple-darwin20)
. Obviously S.O. has an answer for this too: stackoverflow.com/questions/40181521/… -
christianlc about 2 yearsIs an "elegant approach" that isn't available to most user shells, by installed base, actually elegant? Scenarios that require blocking execution, like synchronizing between concurrent/parallel threads of execution, should prioritize portability over anything else - this answer is going to fubar junior/inexperienced operators