#!/bin/bash while : do sl done
How to terminate this bash script?
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
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
Ctrl-Zto suspend the script
%% 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 bg, and
help kill in bash, and search for
JOB CONTROL (all caps) or
jobspec in the bash man page.
$ ./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 + Stopped ./killme.sh $ kill %% $ + Terminated ./killme.sh
In this example, the job's number was 1, so
kill %1 would have worked the same as
(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)
You can terminate that script by pressing Ctrl+C from terminal where you started this script. Of course this script must run in foreground so you are able to stop it by Ctrl+C.
Or you can find PID (Process ID) of that script in other opened terminal by:
ps -ef | grep <name_of_the_script> kill -9 <pid_of_your_running_script>
Both ways should do the trick your are asking for.
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.
Another way to terminate the entire script would be to background the
sl command and then trap signal
INT to kill the entire process group of the script with signal
#!/bin/bash trap 'trap - INT; kill -s HUP -- -$$' INT #trap 'trap - INT; kill -s HUP 0' INT while : do sl & wait done
The killing thing is awful, because you never now, if the script has to run twice. AND your exit code is wrong.
while [ something ]; do if [ somethingelse ]; then echo shut down script with exit code 0 exit 0 fi done echo something else not happend exit 2 # Return val important for example for monitoring
No working. Solution = use perl. while opens own bash