19

I'm writing a stop routine for a start-up service script:

do_stop() { rm -f $PIDFILE pkill -f $DAEMON || return 1 return 0 } 

The problem is that pkill (same with killall) also matches the process representing the script itself and it basically terminates itself. How to fix that?

2
  • use pgrep and loop then kill? Commented Apr 1, 2013 at 9:05
  • I was intending to do that, but asked the question here in case there is a simpler solution. Commented Apr 1, 2013 at 9:07

3 Answers 3

21

You can explicitly filter out the current PID from the results:

kill $(pgrep -f $DAEMON | grep -v ^$$\$) 

To correctly use the -f flag, be sure to supply the whole path to the daemon rather than just a substring. That will prevent you from killing the script (and eliminate the need for the above grep) and also from killing all other system processes that happen to share the daemon's name.

Sign up to request clarification or add additional context in comments.

1 Comment

For me in bash pgrep finds also the pid of the subshell and prints an ugly warning when trying to kill it.
14

pkill -f accepts a full blown regex. So rather than pkill -f $DAEMON you should use:

pkill -f "^"$DAEMON 

To make sure only if process name starts with the given daemon name then only it is killed.

A better solution will be to save pid (Proces Id) of the process in a file when you start the process. And for the stopping the process just read the file to get the process id to be stopped/killed.

3 Comments

"storing the pid" approach will inevitably create more problems than it solves. Keep it simple
This still causes pkill to kill itself, any ideas? < sudo pkill -9 -f "perl.*"debconf/frontend
pkill should not kill itself
1

Judging by your question, you're not hard over on using pgrep and pkill, so here are some other options commonly used.

1) Use killproc from /etc/init.d/functions or /lib/lsb/init-functions (which ever is appropriate for your distribution and version of linux). If you're writing a service script, you may already be including this file if you used one of the other services as an example.

Usage: killproc [-p pidfile] [ -d delay] {program} [-signal] 

The main advantage to using this is that it sends SIGTERM, waits to see if the process terminates and sends SIGKILL only if necessary.

2) You can also use the secret sauce of killproc, which is to find the process ids to kill using pidof which has a -o option for excluding a particular process. The argument for -o could be $$, the current process id, or %PPID, which is a special variable that pidof interprets as the script calling pidof. Finally if the daemon is a script, you'll need the -x so your trying to kill the script by it's name rather than killing bash or python.

for pid in $(pidof -o %PPID -x progd); do kill -TERM $pid done 

You can see an example of this in the article Bash: How to check if your script is already running

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.