3

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
    Commented 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
    Commented Nov 3, 2021 at 16:21

1 Answer 1

0

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
    Commented Nov 2, 2021 at 18:01
  • @terdon /proc/$MYPID/cmdline is not equal to $commandline, e.g. spaces are replaced by \0 . Commented 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
    Commented Nov 3, 2021 at 14:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .