4

Code:

if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then exit; fi

Original source of the code: https://forum.rclone.org/t/continuous-syncing/12377/2

I don't understand how this code inside a bash scrip ensure only one instance of the bash script is running.

I understand the part pidof -x $(basename $0) retrieve the process ID of the script but I don't understand what the part -o %PPID used for.

Question: Do anyone know how the code working?

2
  • Does this answer your question? How does this script ensure that only one instance of itself is running?
    – they
    Nov 22 at 13:33
  • 2
    Using pidof based on basename $0 in any case is an insecure way to perform this check. Two very different programs can have the same basename, after all. So if another program with the same basename is already running, your program will (wrongly) assume that it is already running and thus not start. It is better to have your script check a pid-file upon startup: Read a pid from a file with a fixed name. Check if the process of this pid is running. If not, write your own pid into this file and run; otherwise stop.
    – Alfe
    Nov 22 at 15:54
6

According to the man page of pidof which I missed (thank @cas for remind me):

-o omitpid
          Tells pidof to omit processes with that process id. The
          special pid %PPID can be used to name the parent process
          of the pidof program, in other words the calling shell or
          shell script.

So -o %PPID mean ignore the current running script, just retrieve PID of another instance of the script (if any).

The original code can be rewrite without mixture of backticks and $() for command substitution:

#!/bin/bash

# ensure only one instance of script is running
if pidof -x $(basename $0) -o %PPID > /dev/null
then
    exit
fi

UPDATE: As @Alfe pointed out: "Using pidof based on basename $0 in any case is an insecure way to perform this check. Two very different programs can have the same basename...". Here is another solution based on @Alfe comment using pid-file:

#!/usr/bin/env bash

set -e

pid_file="fixed_name.pid"

# ensure only one instance of script is running
if [ -f "$pid_file" ] && ps -p $(cat "$pid_file") > /dev/null
then
    # another instance of this script is running
    exit
fi

# write script's PID to pid-file
printf "$$" > "$pid_file"

# do some work

I can see one problem in this solution as there can be a valid PID assigned to a different program in a stale PID file. Of course, no solution is perfect. But this gone too far from my original question.

New contributor
leanhtai01 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

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.