Quick-and-dirty way to ensure only one instance of a shell script is running at a time

前端 未结 30 2459
忘掉有多难
忘掉有多难 2020-11-22 02:57

What\'s a quick-and-dirty way to make sure that only one instance of a shell script is running at a given time?

相关标签:
30条回答
  • 2020-11-22 03:07

    Answered a million times already, but another way, without the need for external dependencies:

    LOCK_FILE="/var/lock/$(basename "$0").pid"
    trap "rm -f ${LOCK_FILE}; exit" INT TERM EXIT
    if [[ -f $LOCK_FILE && -d /proc/`cat $LOCK_FILE` ]]; then
       // Process already exists
       exit 1
    fi
    echo $$ > $LOCK_FILE
    

    Each time it writes the current PID ($$) into the lockfile and on script startup checks if a process is running with the latest PID.

    0 讨论(0)
  • 2020-11-22 03:07

    I use oneliner @ the very beginning of script:

    #!/bin/bash
    
    if [[ $(pgrep -afc "$(basename "$0")") -gt "1" ]]; then echo "Another instance of "$0" has already been started!" && exit; fi
    .
    the_beginning_of_actual_script
    

    It is good to see the presence of process in the memory (no matter what the status of process is); but it does the job for me.

    0 讨论(0)
  • 2020-11-22 03:07

    Quick and dirty?

    #!/bin/sh
    
    if [ -f sometempfile ]
      echo "Already running... will now terminate."
      exit
    else
      touch sometempfile
    fi
    
    ..do what you want here..
    
    rm sometempfile
    
    0 讨论(0)
  • 2020-11-22 03:08

    There's a wrapper around the flock(2) system call called, unimaginatively, flock(1). This makes it relatively easy to reliably obtain exclusive locks without worrying about cleanup etc. There are examples on the man page as to how to use it in a shell script.

    0 讨论(0)
  • 2020-11-22 03:08

    Here's an approach that combines atomic directory locking with a check for stale lock via PID and restart if stale. Also, this does not rely on any bashisms.

    #!/bin/dash
    
    SCRIPTNAME=$(basename $0)
    LOCKDIR="/var/lock/${SCRIPTNAME}"
    PIDFILE="${LOCKDIR}/pid"
    
    if ! mkdir $LOCKDIR 2>/dev/null
    then
        # lock failed, but check for stale one by checking if the PID is really existing
        PID=$(cat $PIDFILE)
        if ! kill -0 $PID 2>/dev/null
        then
           echo "Removing stale lock of nonexistent PID ${PID}" >&2
           rm -rf $LOCKDIR
           echo "Restarting myself (${SCRIPTNAME})" >&2
           exec "$0" "$@"
        fi
        echo "$SCRIPTNAME is already running, bailing out" >&2
        exit 1
    else
        # lock successfully acquired, save PID
        echo $$ > $PIDFILE
    fi
    
    trap "rm -rf ${LOCKDIR}" QUIT INT TERM EXIT
    
    
    echo hello
    
    sleep 30s
    
    echo bye
    
    0 讨论(0)
  • 2020-11-22 03:08

    The semaphoric utility uses flock (as discussed above, e.g. by presto8) to implement a counting semaphore. It enables any specific number of concurrent processes you want. We use it to limit the level of concurrency of various queue worker processes.

    It's like sem but much lighter-weight. (Full disclosure: I wrote it after finding the sem was way too heavy for our needs and there wasn't a simple counting semaphore utility available.)

    0 讨论(0)
提交回复
热议问题