Reputation: 65
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
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
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.
Upvotes: 1
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
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