Simplest way I can think of is to get the pid before you launch the process.
For example (in bash):
pidfile() { (
echo $BASHPID > "$1"
shift
exec "$@"
) }
mkfifo /var/run/out
while true
do
pidfile /tmp/cat.pid cat /var/run/out | pidfile /tmp/nc.pid nc -l 8080 > >(
while read line
do
do some stuff
done
)
done
This creates a pidfile
function that writes the current PID to the specified file, and then executes the rest of the arguments using exec
. The exec
causes the command to be run with the same pid as the shell that just wrote out the file.
We wrap the entire pidfile()
function inside parenthesis ()
so that we can ensure it executes in a subshell. The situation where this becomes critical is when you execute a command that isn't in a pipeline. For example:
pidfile /tmp/foo some command here
When you do it this way, pidfile()
is going to run in the same process as the rest of the script, and so when it calls exec
, the command being run will take over the PID, and the script will no longer be running.
Also note, that the above is all written for bash. $BASHPID
is a bash specific variable. $$
does not change when using a subshell, so the value is incorrect for our use.