cla*_*ver 5 bash shell-script lock concurrency
我试图找到一种根据给定参数锁定脚本的方法,但未能成功找到正确的答案。
我想要实现的是防止另一个用户基于某些参数运行脚本:因此,如果用户 A 使用参数执行脚本JOHN_DOE
(例如:-d JOHN_DOE
)并且用户 B 使用参数执行脚本-d ANNA_DOE
,则它运行不会有任何问题,但如果用户B 尝试使用JOHN_DOE
参数来执行它,而脚本的第一个实例尚未完成运行,则不允许用户 B 运行它。
有没有正确的方法来实现这一目标?
诸如此类的工具flock
可以帮助管理锁。(它可能不适用于 NFS,具体取决于您是否相信文档或实践,并且同样可能不适用于 SMB 或任何其他远程文件系统。)
文档man flock
确实有几个使用示例。这是根据您的情况量身定制的其中之一。
#!/bin/bash
# Example of using flock(1) to provide a named exclusive lock
# Parse command line options
while getopts 'd:' OPT
do
case "$OPT" in
d) lockParam="$OPTARG" ;;
*) echo "Usage: ${0##*/} -d <parameter>" >&2; exit 1
esac
done
shift $(($OPTIND -1))
# Sanitise lock parameter value (do not trust the user)
lockName="$(printf "%s\n" "${lockParam^^}" | tr -cd '[:alnum:]\n')"
lockFile="/tmp/lock.${##*/}.${lockName:-noname}"
echo "Attempting lock with parameter '$lockParam' sanitised to '$lockName'" >&2
(
# Get the lock or report failure. See "man flock" for other options
flock -n 9 || exit 9
# This section is managed by the exclusive lock. Your program code
# would go here.
echo "Achieved exclusive lock on '$lockFile'" >&2
sleep=10
echo "Waiting for $sleep second(s) to simulate activity" >&2
sleep $sleep
# Exit status 0=ok, otherwise 1-8 is your choice of error codes
echo "Releasing lock" >&2
exit 0
# End of exclusive lock section
) 9>"$lockFile"
ss=$?
# Report on exit status from actual code
if [ $ss -eq 9 ]
then
echo "Failed to acquire lock" >&2
fi
# Exit with meaning
exit $ss
Run Code Online (Sandbox Code Playgroud)
使脚本可执行(如果您调用它lockeg
then chmod a+x lockeg
),然后运行它
./lockeg -d JOHN_DOE
Run Code Online (Sandbox Code Playgroud)