检查脚本双重执行[重复]
Posted
技术标签:
【中文标题】检查脚本双重执行[重复]【英文标题】:Check script double execution [duplicate] 【发布时间】:2019-07-08 15:16:23 【问题描述】:我有一个 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' 'ENDprint 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
通过这种方式,我检查了我的日志中有多少行,如果结果多于一个,那么我有两个正在执行的进程,一个将被停止。 但是,此方法无法正常工作。如何修复我的代码以检查我有多少正在执行的脚本?
【问题讨论】:
为什么不创建临时文件并处理,因为它是信号量? 什么是调度它? @chepner 我已经安排好了脚本开始的时间。每天在同一时间执行我的脚本 如果您正确配置了调度程序(cron 或任何您使用的),则不会发生这种情况。我建议您解决根本原因,而不是添加花里胡哨。 @AndrejsCainikovs 不幸的是,我不是管理调度程序的人,我无法对其进行操作。我唯一的选择是预测潜在的错误并修复它 【参考方案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.
【讨论】:
【参考方案2】:任何涉及:
-
读取一些状态信息
检查结果
根据结果采取行动
完成
必须同时执行所有三个步骤,否则会出现“竞争”情况。例如:
(A) 读取状态 (A) 检查结果(正常) (A) 执行操作(ok) (A) 完成 (B) 读取状态 (B) 检查结果(差) (B) 采取行动(坏) (B) 完成但如果时间稍有不同:
(A) 读取状态 (A) 检查结果 (ok) (B) 读取状态 (B) 检查结果(正常) (A) 执行操作 (ok) (B) 执行操作(ok) (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
【讨论】:
以上是关于检查脚本双重执行[重复]的主要内容,如果未能解决你的问题,请参考以下文章