Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a command that I want to have run again automatically each time it terminates, so I ran something like this:

while [ 1 ]; do COMMAND; done;

but if I can't stop the loop with Ctrl-c as that just kills COMMAND and not the entire loop.

How would I achieve something similar but which I can stop without having to close the terminal?

share|improve this question
If I'm in bash I just use Ctrl-Z to stop the job and then "kill %1" to kill it. – Paul Cager Jul 4 '12 at 13:20
Just wait... Linus was quoted as saying: “We all know Linux is great... it does infinite loops in 5 seconds.” -- so really... just wait a few more seconds, it should complete. – lornix Jul 5 '12 at 8:40
@PaulCager worked for me too! Why does it work where Ctrl-C does not? – Ciro Santilli 巴拿馬文件 六四事件 法轮功 Mar 15 '14 at 19:19
@cirosantilli it kills the outer job (the bash "wrapper"). In some situations, it won't immediately kill the "COMMAND", for instance, if you background it, it may sneak past alive even if it's parent is dead. But the loop is dead, and that's the important part. – orion Mar 15 '14 at 23:01
up vote 19 down vote accepted

Check the exit status of the command. If the command was terminated by a signal the exit code will be 128 + the signal number. From the GNU online documentation for bash:

For the shell’s purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure. This seemingly counter-intuitive scheme is used so there is one well-defined way to indicate success and a variety of ways to indicate various failure modes. When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.

POSIX also specifies that the value of a command that terminated by a signal is greater than 128, but does not seem to specify its exact value like GNU does:

The exit status of a command that terminated because it received a signal shall be reported as greater than 128.

For example if you interrupt a command with control-C the exit code will be 130, because SIGINT is signal 2 on Unix systems. So:

while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
share|improve this answer
It should be mentioned that this is not guaranteed, in fact, many applications will not do this. – Chris Down Jul 4 '12 at 1:18
@Kyle Jones: can you link to the POSIX / GNU docs that mention that? – Ciro Santilli 巴拿馬文件 六四事件 法轮功 Mar 15 '14 at 20:03
@cirosantilli Done. – Kyle Jones Mar 15 '14 at 22:44
@KyleJones thanks! Still in practice not working for COMMAND = paplay alert.ogg, perhaps because paplay handles the signal? – Ciro Santilli 巴拿馬文件 六四事件 法轮功 Mar 16 '14 at 6:49
@cirosantilli Yes, that's the reason. If a process handles the signal and quits, that's different than the process being terminated by an unhandled signal. – Kyle Jones Mar 16 '14 at 7:21

I generally just hold down Ctrl-C. Sooner or later it'll register between COMMAND's and thus terminate the while loop. Maybe there is a better way.

share|improve this answer
Not sure why, but it fails for certain COMMANDs like paplay on a 1s file. – Ciro Santilli 巴拿馬文件 六四事件 法轮功 Mar 15 '14 at 11:07
It worked for me – alexandr May 28 '15 at 10:56

You can stop and put your job in background while it's running using ctrl+z. Then you can kill your job with:

$ kill %1

Where [1] is your job number.

share|improve this answer
See also this answer for explanations and more. – Skippy le Grand Gourou Aug 3 '14 at 10:33
This relatively recent answer just simply works. Needs to be upvoted. +1 – shivams Jul 23 '15 at 20:17
You helped me a lot. This is what i have searched for in this question :) – Maximilian Ruta Sep 14 '15 at 8:10

I would say it might be best to put your infinite loop in a script and handle signals there. Here's a basic starting point. I'm sure you'll want to modify it to suit. The script uses trap to catch ctrl-c (or SIGTERM), kills off the command (I've used sleep here as a test) and exits.

cleanup ()
kill -s SIGTERM $!
exit 0

trap cleanup SIGINT SIGTERM

while [ 1 ]
    sleep 60 &
    wait $!
share|improve this answer
Nice. Here's how I used this tip to make an autorestarting netcat wrapper: trap "exit 0" SIGINT SIGTERM; while true; do netcat -l -p 3000; done – Douglas Jan 13 '13 at 13:00

If you run bash with -e it will exit on any error conditions:

#!/bin/bash -e
false # returns 1
echo This won't be printed
share|improve this answer
This will definitely come in handy. – Dean Jul 4 '12 at 7:21
  1. You can always kill a process using its PID, there's no need to close your terminal
  2. If you want to run something in an infinite loop like a daemon then you'd best put it in the background
  3. while : will create an infinite loop and saves you writing the [ 1 ]

    while :; do COMMAND; done &

This will print the PID. If you exit your prompt using ctrl+d then the background job won't quit, and you can later kill the job from anywhere using kill PID

If you lose track of your PID, you can use pstree -pa $USER or pgrep -fl '.*PROCESS.*' to help you find it

share|improve this answer

Why not simply,

while [ 1 ]; do COMMAND || break; done;

Or when used in a script,

while [ 1 ]; do
  # ctrl+c terminates COMMAND and exits the while loop
  # (assuming COMMAND responds to ctrl+c)
  COMMAND || break
share|improve this answer
Very elegant solution. But wouldn't this only work if COMMAND always returns a success exit status? – howardh Dec 5 '15 at 1:04
Yes @howardh, that's correct. – Dale A Dec 7 '15 at 17:29

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.