How to stop the loop bash script in terminal?
- press
Ctrl-Z
to suspend the script kill %%
The %%
tells the bash built-in kill
that you want to send a signal (SIGTERM by default) to the most recently suspended background job in the current shell, not to a process-id.
You can also specify jobs by number or by name. e.g. when you suspend a job with ^Z, bash will tell you what its job number is with something like [n]+ Stopped
, where the n
inside the square brackets is the job number.
For more info on job control and on killing jobs, run help jobs
, help fg
, help bg
, and help kill
in bash, and search for JOB CONTROL
(all caps) or jobspec
in the bash man page.
e.g.
$ ./killme.sh ./killme.sh: line 4: sl: command not found ./killme.sh: line 4: sl: command not found ./killme.sh: line 4: sl: command not found ./killme.sh: line 4: sl: command not found ./killme.sh: line 4: sl: command not found ... ... ... ./killme.sh: line 4: sl: command not found ^Z [1]+ Stopped ./killme.sh $ kill %% $ [1]+ Terminated ./killme.sh
In this example, the job's number was 1, so kill %1
would have worked the same as kill %%
(NOTE: I don't have sl
installed so the output is just "command not found". in your case, you'll get whatever output sl produces. it's not important - the ^Z
suspend and kill %%
will work the same)
The program sl
purposely ignores SIGINT
, which is what gets sent when you press Ctrl+C. So, firstly, you'll need to tell sl
not to ignore SIGINT
by adding the -e
argument.
If you try this, you'll notice that you can stop each individual sl
, but they still repeat. You need to tell bash
to exit after SIGINT
as well. You can do this by putting a trap "exit" INT
before the loop.
#!/bin/bash
trap "exit" INT
while :
do
sl -e
done
If you want ctrl+c to stop the loop, but not terminate the script, you can place || break
after whatever command you're running. As long as the program you're running terminates on ctrl+c, this works great.
#!/bin/bash
while :
do
# ctrl+c terminates sl, but not the shell script
sl -e || break
done
If you're in nested loop, you can use "break 2" to get out of two levels, etc.