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". 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. 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. 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? Commented Nov 3, 2021 at 14:07

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.