How to stop the loop bash script in terminal?

  1. press Ctrl-Z to suspend the script
  2. 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.

Tags:

Bash

Signals

Trap