11

In the current situation, a certain script 'calling.sh' launches another script 'called.sh' in the background, performs other operations, sleeps for a while, and then terminates 'called.sh' with a pkill called.sh. This works fine.

Then, I would also like to launch 'called.sh' from other terminals as a standalone script at any other time, whether before or after launching calling.sh. These independent instances should not be killed by 'calling.sh'.

How can I achieve this? Intuition says that the calling script should be able to tell the process it started from any other namesakes that are running in the meantime.

As a variant, 'calling.sh' may also launch 'called' which is a symbolic link to 'called.sh'. Does this complicate managing the above situation? Which specific cautions and adjustments does using a symbolic link require?

27

Don't use the name to kill it. Since the calling.sh script is calling the process you later want to kill, just use $! (from man bash):

! Expands to the process ID of the job most recently placed into the background, whether executed as an asynchronous command or using the bg builtin

So, if you're calling.sh is like this:

called.sh &
## do stuff
pkill called.sh

Change it to this:

called.sh &
calledPid=$!
# do stuff
kill "$calledPid"
  • 4
    This should work as long as called.sh does not die by itself, because otherwise its pid might be reused, killing an innocent and unrelated process as a result. – Eugene Ryabtsev Mar 12 at 12:05
  • 2
    @EugeneRyabtsev that's a very good point. I guess you could also check that the $calledPid's parent PID is the PID of called.sh. – terdon Mar 12 at 12:18
  • To reinforce the answer, this is another resource I found useful to organize my thoughts: mywiki.wooledge.org/ProcessManagement – XavierStuvw Mar 12 at 16:45
18

I've had to pick this but out of scripts so many times; it's even more fun when the scripts are called as part of a complex automated schedule. You really shouldn't rely on something like pkill to select which script to kill.

Inside of calling.sh you should record the PIDs of the jobs you have started and kill them explicitly by PID.

Inside calling.sh:

./called.sh &
called_pid=$!

# Later
kill $called_pid

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.