简体   繁体   中英

Can't kill a Bash command that sleeps in a loop

I tried to run

$ (while true; do cat some_small_file ; sleep 1; done) | some_script

to test some_script , but some_script wasn't in my $PATH , so that printed

some_script command not found

The weird things is that Bash did not return, and Ctrl-C does nothing.

I even tried killing sleep with

ps -u maxb | grep sleep | cut -f1 -d " " | xargs kill -9

in another terminal, but that, of course just continues to the next loop iteration.

Is it possible to make Bash terminate that command?

There are a few approaches you can take here.

One is to move both cat and sleep into the conditional part of the while syntax, such that the loop will fail as soon as either of those commands does not succeed:

while cat some_small_file && sleep 1; do :; done | some_script

A similar option is to put an explicit break into the loop, conditioned (again) on such failure:

while :; do cat some_small_file && sleep 1 || break; done | some_script

Note that : is an exact synonym for true . (In every shell I've seen -- not just bash but even Busybox ash -- they're literally implemented by the same internal function).


Also note that the most important part of this solution is exiting the loop if cat fails, not if sleep fails: Exiting on a sleep failure will address the kill problem, but exiting on a cat failure will handle the (much more likely) case that some_script has exited and thus writing to it is resulting in a SIGPIPE .


By the way -- either removing the ( ) s outright or replacing them with { ...; } { ...; } is appropriate as a way to potentially reduce the number of transient subshells: While pipelines always create implicit subshells, there's no particular reason to use syntax that may (in some cases -- there are pertinent details which are implementation- rather than standard-defined) create an explicit subshell in addition to the mandatory implicit one(s).

It's thus a very minor efficiency improvement, but not essential to this answer: You'd get the same behavior if you stuck with the original parenthesis but modified the flow control constructs in the same way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM