100 linux bash lockfile pid flock
确保只有给定脚本的一个实例运行的最简单/最好的方法是什么 - 假设它是Linux上的Bash?
目前我正在做:
ps -C script.name.sh > /dev/null 2>&1 || ./script.name.sh
Run Code Online (Sandbox Code Playgroud)
但它有几个问题:
-C 仅检查进程名称的前14个字符当然,我可以编写自己的pidfile处理,但我觉得应该有一个简单的方法来实现它.
prz*_*moc 139
咨询锁定已经使用了很长时间,它可以在bash脚本中使用.我更喜欢简单flock(从util-linux[-ng])到lockfile(从procmail).并始终记住这些脚本中退出时的陷阱(sigspec == EXIT或0捕获特定信号是多余的).
在2009年,我发布了我的可锁定脚本样板(最初在我的维基页面上提供,现在可以作为要点).将其转换为每用户一个实例是微不足道的.使用它,您还可以轻松地为需要某些锁定或同步的其他场景编写脚本.
为方便起见,这是上面提到的样板.
#!/bin/bash
# SPDX-License-Identifier: MIT
## Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com>
##
## This script is licensed under the terms of the MIT license.
## https://opensource.org/licenses/MIT
#
# Lockable script boilerplate
### HEADER ###
LOCKFILE="/var/lock/`basename $0`"
LOCKFD=99
# PRIVATE
_lock() { flock -$1 $LOCKFD; }
_no_more_locking() { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking() { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }
# ON START
_prepare_locking
# PUBLIC
exlock_now() { _lock xn; } # obtain an exclusive lock immediately or fail
exlock() { _lock x; } # obtain an exclusive lock
shlock() { _lock s; } # obtain a shared lock
unlock() { _lock u; } # drop a lock
### BEGIN OF SCRIPT ###
# Simplest example is avoiding running multiple instances of script.
exlock_now || exit 1
# Remember! Lock file is removed when one of the scripts exits and it is
# the only script holding the lock or lock is not acquired at all.
Run Code Online (Sandbox Code Playgroud)
ezp*_*zpz 102
如果所有用户的脚本相同,则可以使用lockfile方法.如果获得锁定,请继续显示消息并退出.
举个例子:
[Terminal #1] $ lockfile -r 0 /tmp/the.lock
[Terminal #1] $
[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] lockfile: Sorry, giving up on "/tmp/the.lock"
[Terminal #1] $ rm -f /tmp/the.lock
[Terminal #1] $
[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] $
Run Code Online (Sandbox Code Playgroud)
后/tmp/the.lock已经获得你的脚本将是唯一一个能够访问执行.完成后,只需取下锁即可.在脚本形式中,这可能如下所示:
#!/bin/bash
lockfile -r 0 /tmp/the.lock || exit 1
# Do stuff here
rm -f /tmp/the.lock
Run Code Online (Sandbox Code Playgroud)
Jak*_*ger 34
我认为flock这可能是最简单(也是最难忘)的变种.我在cron作业中使用它来自动编码dvds和cds
# try to run a command, but fail immediately if it's already running
flock -n /var/lock/myjob.lock my_bash_command
Run Code Online (Sandbox Code Playgroud)
使用-w了超时或离开了选择等待,直到锁被释放.最后,手册页显示了多个命令的一个很好的示例:
(
flock -n 9 || exit 1
# ... commands executed under lock ...
) 9>/var/lock/mylockfile
Run Code Online (Sandbox Code Playgroud)
set -o noclobber选项并尝试覆盖公共文件.if ! (set -o noclobber ; echo > /tmp/global.lock) ; then
exit 1 # the global.lock already exists
fi
# ... remainder of script ...
Run Code Online (Sandbox Code Playgroud)
此示例将等待global.lock文件,但在过长时间后超时.
function lockfile_waithold()
{
declare -ir time_beg=$(date '+%s')
declare -ir time_max=7140 # 7140 s = 1 hour 59 min.
# poll for lock file up to ${time_max}s
# put debugging info in lock file in case of issues ...
while ! \
(set -o noclobber ; \
echo -e "DATE:$(date)\nUSER:$(whoami)\nPID:$$" > /tmp/global.lock \
) 2>/dev/null
do
if [ $(($(date '+%s') - ${time_beg})) -gt ${time_max} ] ; then
echo "Error: waited too long for lock file /tmp/global.lock" 1>&2
return 1
fi
sleep 1
done
return 0
}
function lockfile_release()
{
rm -f /tmp/global.lock
}
if ! lockfile_waithold ; then
exit 1
fi
trap lockfile_release EXIT
# ... remainder of script ...
Run Code Online (Sandbox Code Playgroud)
(这与@Barry Kelly的这篇文章类似,后来被注意到了.)
| 归档时间: |
|
| 查看次数: |
96690 次 |
| 最近记录: |