MakeThingsHappen
MakeThingsHappen

Reputation: 65

how to kill a single background process in bash

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.

Upvotes: 1

Views: 1788

Answers (4)

zerodiff
zerodiff

Reputation: 1700

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

Upvotes: 1

OldGeeksGuide
OldGeeksGuide

Reputation: 2918

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

Upvotes: 1

probinso
probinso

Reputation: 307

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

Upvotes: 1

Alexander Craggs
Alexander Craggs

Reputation: 8759

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

Upvotes: 1

Related Questions