有什么快速而简单的方法可以确保在给定时间内只有一个shell脚本实例在运行?


当前回答

我想要去掉锁文件,锁dirs,特殊的锁程序,甚至pidof,因为它不是在所有的Linux安装中都能找到的。还希望有尽可能简单的代码(或至少尽可能少的行)。最简单的if语句,在一行中:

if [[ $(ps axf | awk -v pid=$$ '$1!=pid && $6~/'$(basename $0)'/{print $1}') ]]; then echo "Already running"; exit; fi

其他回答

这个例子是在man flock中解释的,但它需要一些改进,因为我们应该管理bug和退出代码:

   #!/bin/bash
   #set -e this is useful only for very stupid scripts because script fails when anything command exits with status more than 0 !! without possibility for capture exit codes. not all commands exits >0 are failed.

( #start subprocess
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200
  if [ "$?" != "0" ]; then echo Cannot lock!; exit 1; fi
  echo $$>>/var/lock/.myscript.exclusivelock #for backward lockdir compatibility, notice this command is executed AFTER command bottom  ) 200>/var/lock/.myscript.exclusivelock.
  # Do stuff
  # you can properly manage exit codes with multiple command and process algorithm.
  # I suggest throw this all to external procedure than can properly handle exit X commands

) 200>/var/lock/.myscript.exclusivelock   #exit subprocess

FLOCKEXIT=$?  #save exitcode status
    #do some finish commands

exit $FLOCKEXIT   #return properly exitcode, may be usefull inside external scripts

你可以用另一种方法,列出我过去用过的过程。但这比上面的方法要复杂得多。你应该按ps列出进程,按其名称过滤,附加过滤器grep -v grep清除寄生虫,最后按grep -c计数。和数字比较。这是复杂而不确定的

下面这一行的回答来自一个与Ask Ubuntu问答相关的人:

[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
#     This is useful boilerplate code for shell scripts.  Put it at the top  of
#     the  shell script you want to lock and it'll automatically lock itself on
#     the first run.  If the env var $FLOCKER is not set to  the  shell  script
#     that  is being run, then execute flock and grab an exclusive non-blocking
#     lock (using the script itself as the lock file) before re-execing  itself
#     with  the right arguments.  It also sets the FLOCKER env var to the right
#     value so it doesn't run again.

如果您不想或不能使用flock(例如,您没有使用共享文件系统),请考虑使用外部服务,如lockable。

它暴露了咨询锁原语,就像flock一样。特别地,你可以通过以下方式获取锁:

https://lockable.dev/api/acquire/my-lock-name

然后通过

https://lockable.dev/api/release/my-lock-name

通过将脚本执行与锁获取和释放结合在一起,您可以确保在任何给定时间只有一个流程实例在运行。

试试下面的方法,

ab=`ps -ef | grep -v grep | grep -wc processname`

然后使用if循环将变量与1匹配。

使用进程的锁更强大,还可以处理不合理的退出。 只要进程在运行,Lock_file就保持打开状态。一旦进程存在,它将被关闭(通过shell)(即使它被杀死)。 我发现这个方法非常有效:

lock_file=/tmp/`basename $0`.lock

if fuser $lock_file > /dev/null 2>&1; then
    echo "WARNING: Other instance of $(basename $0) running."
    exit 1
fi
exec 3> $lock_file