2

In our application, we start some background processes. The pid of these processes is saved to a file.

pids values are re-used when the maximum is reached or when the system is rebooted.

How can I reliably check that the process with pid X is still the same process for which X was stored.

I've read https://serverfault.com/questions/366474/whats-a-proper-way-of-checking-if-a-pid-is-running and https://stackoverflow.com/questions/3043978/how-to-check-if-a-process-id-pid-exists but these solutions never check if the process that has pid X is the still same process as the one for which the pid was stored.

I need this info to reliably

  • check the process is still running
  • kill the process without risking to kill a different process that now has pid X

related https://serverfault.com/questions/279178/what-is-the-range-of-a-pid-on-linux-and-solaris

I will post my current solution. I'd like to know if it's a sensible approach and if there are better ways to do this.

2
  • This only answers half of your question, but you can check if a process exists and is running with kill -0 $pid; e. g. if kill -0 "$pid"; then printf "PID %d exists and is running.\n" "$pid".
    – DopeGhoti
    Nov 2, 2021 at 17:08
  • It seems you are reinventing service manager, if so, wrapping your background process into a systemd service should be easy and reliable.
    – AnyDev
    Nov 3, 2021 at 16:21

1 Answer 1

-1

I created following solution for this

My start script contains

nohup $commandline >> $TEMP/logfile 2>&1 &
MYPID=$!
echo $MYPID > pidfile
cat /proc/$MYPID/cmdline >> pidfile

My stop script reads the pidfile and checks if the cmdline corresponds to the one originally saved

[ -f pidfile ] || { echo no pidfile; exit 1; }
read pid < pidfile
psatstart=$(tail -1 pidfile)
psnow=$(</proc/$pid/cmdline)

if [[ "$psnow" == "$psatstart" ]]
then
    echo kill $pid
    kill $pid || { echo kill $pid failed; exit 2; }
    while ps -p $pid
    do
        sleep 1
    done
else
    echo pid $pid not the same, assume already ended
    echo S $psatstart
    echo N $psnow
fi
rm pidfile
3
  • Why cat /proc/$MYPID/cmdline >> pidfile instead of printf '%s\n' "$commandline" >> pidfile? You already have the command line after all.
    – terdon
    Nov 2, 2021 at 18:01
  • @terdon /proc/$MYPID/cmdline is not equal to $commandline, e.g. spaces are replaced by \0 . Nov 3, 2021 at 14:02
  • Precisely, and this breaks the approach since even if you were to fix the wrong psnow=$(/proc/$pid/cmdline), and change it to psnow=$(cat /proc/$pid/cmdline) which is presumably what you want, it will lose the \0 since \0 cannot be stored in shell variables. So, since you already have the command line stored in a variable, why not use that directly and avoid the problem?
    – terdon
    Nov 3, 2021 at 14:07

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.