1

I want to kill a single background process in bash

$SCRIPT_DIR/utils/monitor.sh -f $root/save &
$SCRIPT_DIR/utils/run.sh -f $save
$SCRIPT_DIR/utils/Monkey.sh  -f $save

I want to kill monitor.sh after finishing Monkey.sh.

I tried using pid but its not working.

4 Answers4

1

You have a multiple options:

First, you can use kill. But you need the pid of your process, which you can get by using ps, pidof or pgrep.

ps -A  // to get the pid, can be combined with grep
-or-
pidof <name>
-or-
pgrep <name>

kill <pid>

It is possible to kill a process by just knowing the name. Use pkill or killall.

pkill <name>
-or-
killall <name>

All commands send a signal to the process. If the process hung up, it might be neccessary to send a sigkill to the process (this is signal number 9, so the following examples do the same):

pkill -9 <name>
pkill -SIGKILL <name>

You can use this option with kill and killall, too.

Read this article about controlling processes to get more informations about processes in general.

Credit goes to tanascius

You should try

killall Monkey.sh
Alexander Craggs
  • 7,874
  • 4
  • 24
  • 46
  • no it doesnot work...i tried killall monitor.sh...pkill monitor.sh but no luck ...the background process is continously running only – MakeThingsHappen Aug 13 '14 at 21:34
1

you are looking for the 'jobs' and 'kill' command

$ ls -l
    total 4.0K
    -rwxr-xr-x. 1 probinson probinso 52 Aug 13 14:25 x.sh
    lrwxrwxrwx. 1 probinson probinso  4 Aug 13 14:28 y.sh -> x.sh
    lrwxrwxrwx. 1 probinson probinso  4 Aug 13 14:28 z.sh -> y.sh

$ cat x.sh 
    for i in $(find / 2> /dev/null ); do echo ${i} &> /dev/null; done

$ ./x.sh & ./y.sh & ./z.sh &
$ jobs
    [1]   Running                 ./x.sh &
    [2]-  Running                 ./y.sh &
    [3]+  Running                 ./z.sh &
$ kill %2
$ jobs
    [1]   Running                 ./x.sh &
    [2]-  Terminated              ./y.sh &
    [3]+  Running                 ./z.sh &
$ jobs
    [1]-  Running                 ./x.sh &
    [3]+  Running                 ./z.sh &

# this should kill job one after job three finishes
$ ./x.sh; x.sh & y.sh & z.sh; kill %1
probinso
  • 309
  • 2
  • 9
1

It looks like the problem might be related to how monitor.sh is called. If I have a script 'foo.sh' that just has a shell command in it, I won't see it identified as 'foo.sh' in a ps listing, but if I call it with sh (or bash) then I do. It seems that if 'foo.sh' is a list of shell commands, the shell will change that to bash , and you won't see 'foo.sh' in the ps listing, but if I explicitly call it with bash, i.e.

bash foo.sh

then I see it in the ps listing.

However, best practice for shell scripts, is to start off with the appropriate 'hashbang' command, i.e. for a bash script the first line should be

#!/bin/bash

this also seems to fix the problem for me. I'm guessing that this line may be missing from monitor.sh, and that's why you don't see it using ps or killall. Once that's in place, you should be able to do

killall -9 monitor.sh

or similar and it will work. Either that or invoke it as bash monitor.sh, but common best practice is to include that first line either way.

cf - http://www.unix.com/shell-programming-and-scripting/21446-ps-command-does-not-display-shell-script-running.html

OldGeeksGuide
  • 2,888
  • 13
  • 23
1

Another way to do this is to save the PID of the backgrounded process:

$SCRIPT_DIR/utils/monitor.sh -f $root/save &
MONITOR_PID=$!
...
kill $MONITOR_PID

The advantage of this over killall is that it will kill this specific process. If you have more than one copy of the script running, this won't kill the other monitor.sh scripts that are running concurrently.

See also: https://stackoverflow.com/a/1911387/1563512

Community
  • 1
  • 1
zerodiff
  • 1,690
  • 1
  • 18
  • 23