Set trap in bash for different process with PID known

4.2k views Asked by At

I need to set a trap for a bash process I'm starting in the background. The background process may run very long and has its PID saved in a specific file.

Now I need to set a trap for that process, so if it terminates, the PID file will be deleted.

Is there a way I can do that?

EDIT #1

It looks like I was not precise enough with my description of the problem. I have full control over all the code, but the long running background process I have is this:

cat /dev/random >> myfile&

When I now add the trap at the beginning of the script this statement is in, $$ will be the PID of that bigger script not of this small background process I am starting here.

So how can I set traps for that background process specifically?

4

There are 4 answers

0
Anya Shenanigans On
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
3
Dennis Williamson On

Add this to the beginning of your Bash script.

#!/bin/bash
trap 'rm "$pidfile"; exit' EXIT SIGQUIT SIGINT SIGSTOP SIGTERM ERR
pidfile=$(tempfile -p foo -s $$)
echo $$ > "$pidfile"
# from here, do your long running process
0
hlovdal On

You do not need trap to just run some command after a background process terminates, you can instead run through a shell command line and add the command following after the background process, separated with semicolon (and let this shell run in the background instead of the background process).

If you still would like to have some notification in your shell script send and trap SIGUSR2 for instance:

#!/bin/sh

BACKGROUND_PROCESS=xterm         # for my testing, replace with what you have

sh -c "$BACKGROUND_PROCESS; rm -f the_pid_file; kill -USR2 $$" &

trap "echo $BACKGROUND_PROCESS ended" USR2

while sleep 1
do
    echo -n .
done
0
ralf23 On

You can run your long running background process in an explicit subshell, as already shown by Petesh's answer, and set a trap inside this specific subshell to handle the exiting of your long running background process. The parent shell remains unaffected by this subshell trap.

(
trap '
  trap - EXIT ERR
  kill -0 ${!} 1>/dev/null 2>&1 && kill ${!}
  rm -f pidfile.pid
  exit
' EXIT QUIT INT STOP TERM ERR
# simulate background process
sleep 15 & 
echo ${!} > pidfile.pid
wait
) &
disown

# remove background process by hand
# kill -TERM ${!}