有什么快速而简单的方法可以确保在给定时间内只有一个shell脚本实例在运行?
当前回答
你需要一个原子操作,比如flock,否则最终会失败。
但是如果没有羊群,该怎么办呢?这是mkdir。这也是一个原子操作。只有一个进程会成功执行mkdir,其他进程都会失败。
所以代码是:
if mkdir /var/lock/.myscript.exclusivelock
then
# do stuff
:
rmdir /var/lock/.myscript.exclusivelock
fi
你需要处理陈旧的锁,否则崩溃后你的脚本将永远不会再次运行。
其他回答
我想要去掉锁文件,锁dirs,特殊的锁程序,甚至pidof,因为它不是在所有的Linux安装中都能找到的。还希望有尽可能简单的代码(或至少尽可能少的行)。最简单的if语句,在一行中:
if [[ $(ps axf | awk -v pid=$$ '$1!=pid && $6~/'$(basename $0)'/{print $1}') ]]; then echo "Already running"; exit; fi
试试下面的方法,
ab=`ps -ef | grep -v grep | grep -wc processname`
然后使用if循环将变量与1匹配。
这个我在任何地方都没有发现,它使用read,我不确切地知道read是否实际上是原子的,但到目前为止它对我来说很有用……它很有趣,因为它只是bash内置的,这是一个进程内实现,你启动locker协进程并使用它的I / O来管理锁,同样可以在进程间完成,只需将目标I / O从locker文件描述符交换到文件系统上的文件描述符(exec 3<>/file && exec 4</file)
## gives locks
locker() {
locked=false
while read l; do
case "$l" in
lock)
if $locked; then
echo false
else
locked=true
echo true
fi
;;
unlock)
if $locked; then
locked=false
echo true
else
echo false
fi
;;
*)
echo false
;;
esac
done
}
## locks
lock() {
local response
echo lock >&${locker[1]}
read -ru ${locker[0]} response
$response && return 0 || return 1
}
## unlocks
unlock() {
local response
echo unlock >&${locker[1]}
read -ru ${locker[0]} response
$response && return 0 || return 1
}
已经回答了一百万次了,但是另一种方式,不需要外部依赖:
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
每次它将当前PID($$)写入锁文件,并在脚本启动时检查进程是否正在使用最新的PID运行。
if [ 1 -ne $(/bin/fuser "$0" 2>/dev/null | wc -w) ]; then
exit 1
fi