检查脚本是否重复执行

时间:2019-02-14 14:45:07

标签: linux bash

我有一个bash脚本,有时甚至发生,即使我的脚本是预定的,它也执行了两次。因此,我添加了几行代码来检查脚本是否已在执行中。最初我没有问题,但是最近三天我又遇到了问题

PID=`echo $$`
PROCESS=${SL_ROOT_FOLDER}/xxx/xxx/xxx_xxx_$PID.txt     
ps auxww | grep $scriptToVerify | grep -v $$ | grep -v grep > $PROCESS
num_proc=`awk -v RS='\n' 'END{print NR}' $PROCESS`
if [ $num_proc -gt 1 ];
then
  sl_log "---------------------------Warning---------------------------"
  sl_log "$scriptToVerify already executed"
  sl_log "num proc $num_proc"
  sl_log "--------"
  sl_log $PROCESS
  sl_log "--------"
  exit 0;
fi

通过这种方式,我检查了日志中有多少行,如果结果多于一行,则我有两个正在执行的进程,一个将被停止。 但是,此方法无法正常工作。如何修复代码以检查执行中的脚本有多少?

2 个答案:

答案 0 :(得分:1)

涉及到的一切:

  1. 阅读一些状态信息
  2. 检查结果
  3. 根据结果采取行动
  4. 完成

必须同时执行所有三个步骤,否则会出现“竞赛”情况。例如:

  • (A)读取状态
  • (A)检查结果(确定)
  • (A)采取行动(确定)
  • (A)完成
  • (B)读取状态
  • (B)检查结果(不好)
  • (B)做事(不好)
  • (B)完成

但如果时间略有不同:

  • (A)读取状态
  • (A)检查结果(确定)
    • (B)读取状态
    • (B)检查结果(确定)
  • (A)采取行动(确定)
    • (B)采取行动(确定)
  • (A)完成
    • (B)完成

人们通常给出的示例是更新银行余额。

使用您的方法,可以减少不应执行的代码的运行频率,但您永远无法完全避免。

更好的解决方案是使用锁定。这样可以保证一次只能运行一个进程。例如,使用flock,您可以将所有调用包装到脚本中:

flock -x /var/lock/myscript-lockfile myscript

或者,在脚本中,您可以执行以下操作:

exec 300>/var/lock/myscript-lockfile
flock -x 300

# rest of script

flock -u 300

或:

exec 300>/var/logk/myscript-lockfile
if ! flock -nx 300; then
    # another process is running
    exit 1
fi

# rest of script

flock -u 300

答案 1 :(得分:1)

flock(1)

#!/bin/bash

# Makes sure we exit if flock fails.
set -e

(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock

这可确保“(”和“)”之间的代码一次仅由一个进程运行,并且该进程确实等待锁定的时间太长。

Credit goes to Alex B