Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

For example,

#!/bin/bash
while :
do
    sl
done

How to terminate this bash script?

share|improve this question
1  
Give more details. Do you want to stop it interactively or programmatically? –  manatwork Sep 17 '12 at 15:57
    
you can press ctrl-c to send the SIGINT signal (in most shells) or you can press ctrl-z that sends the SIGTSTP signal (in most shells). In the case you pressed ctrl-z the related process isn't killed but paused. You can resume it with fg (at least in bash) –  user1146332 Sep 17 '12 at 15:59
    
No, it doesn't work! –  Yinyanghu Sep 17 '12 at 16:16
    
@manatwork interactively!! –  Yinyanghu Sep 17 '12 at 16:20
1  
The problem is not the script, but the sl command which I believe is an annoing command for those who misspell ls, showing a train passing slowly by. As far as I know it traps the SIGINT signal and must be killed with SIGKILL. –  Herman Torjussen Sep 17 '12 at 16:48

5 Answers 5

up vote 12 down vote accepted

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
share|improve this answer
    
Perfect answer! –  Yinyanghu Sep 17 '12 at 17:01
1  
I don't have it installed to check, but you might also be able to kill it with SIGQUIT from Ctrl-\ –  derobert Sep 17 '12 at 17:36
  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)

share|improve this answer
    
Another good answer! –  Yinyanghu Sep 18 '12 at 2:25
    
BTW, for rapidly executing loops like this, ^Z can be a more reliable way to kill the process than ^C. ^C will be sent to the program (sl) being run in the loop, but the script will keep running...and start another sl. If you press ^C a few times really fast, you may get to kill both the sl and the script (if neither of them trap SIGINT). ^Z will suspend the script almost immediately (immediately if you don't count buffered output that is still being printed to your terminal), so you can kill it with kill %% –  cas Sep 18 '12 at 2:48
    
Exactly! I have to say "sl is a fun program". This time, it fun me again! @_@ –  Yinyanghu Sep 18 '12 at 3:07

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.

share|improve this answer
    
It can't be terminated by Ctrl+C from terminal. So I have to kill it by ps or top. I just want to know how to kill it directly! –  Yinyanghu Sep 17 '12 at 16:15

You can kill the pid of shell (bash).
I just tried and it works.
Because I cannot see the process from ps -ef (the job that we run in the looping script).

share|improve this answer
while [ true ] 
do

  ps | grep script_name.sh | grep -v grep >/dev/null 2>&1

  if [ "$!" = "0" ] ; then
    break
  else
    kill -9 ` ps -ef | grep script_name.sh | cut -d "a" -f 1` 
  fi

done

this should help.

share|improve this answer
    
Why do you think the PID of the last background command will ever be 0? –  manatwork Aug 8 '13 at 13:18

Your Answer

 
discard

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.