How to make sure only one instance of a Bash script is running at a time?

前端 未结 6 1869
时光取名叫无心
时光取名叫无心 2021-02-08 00:54

I want to make a sh script that will only run at most once at any point.

Say, if I exec the script then I go to exec the script again, how do I make it so that if the f

6条回答
  •  -上瘾入骨i
    2021-02-08 01:11

    I just wrote a tool that does this: https://github.com/ORESoftware/quicklock

    writing a good one takes about 15 loc, so not something you want to include in every shell script.

    basically works like this:

    $ ql_acquire_lock
    

    the above calls this bash function:

    function ql_acquire_lock {
      set -e;
      name="${1:-$PWD}"  # the lock name is the first argument, if that is empty, then set the lockname to $PWD
      mkdir -p "$HOME/.quicklock/locks"
      fle=$(echo "${name}" | tr "/" _)
      qln="$HOME/.quicklock/locks/${fle}.lock"
      mkdir "${qln}" &> /dev/null || { echo "${ql_magenta}quicklock: could not acquire lock with name '${qln}'${ql_no_color}."; exit 1; }
      export quicklock_name="${qln}";  # export the var *only if* above mkdir command succeeds
      trap on_ql_trap EXIT;
    }
    

    when the script exits, it automatically releases the lock using trap

    function on_ql_trap {
       echo "quicklock: process with pid $$ was trapped.";
       ql_release_lock
    }
    

    to manually release the lock at will, use ql_release_lock:

    function ql_maybe_fail {
      if [[ "$1" == "true" ]]; then
          echo -e "${ql_magenta}quicklock: exiting with 1 since fail flag was set for your 'ql_release_lock' command.${ql_no_color}"
          exit 1;
      fi
    }
    
    function ql_release_lock () {
    
       if [[ -z "${quicklock_name}" ]]; then
         echo -e "quicklock: no lockname was defined. (\$quicklock_name was not set).";
         ql_maybe_fail "$1";
         return 0;
       fi
    
       if [[ "$HOME" == "${quicklock_name}" ]]; then
         echo -e "quicklock: dangerous value set for \$quicklock_name variable..was equal to user home directory, not good.";
         ql_maybe_fail "$1"
         return 0;
       fi
    
       rm -r "${quicklock_name}" &> /dev/null &&
       { echo -e "quicklock: lock with name '${quicklock_name}' was released.";  } ||
       { echo -e "quicklock: no lock existed for lockname '${quicklock_name}'."; ql_maybe_fail "$1"; }
       trap - EXIT  # clear/unset trap
    
    }
    

提交回复
热议问题