我试图找到一种根据给定参数锁定脚本的方法,但未能成功找到正确的答案。
我想要实现的是防止另一个用户基于某些参数运行脚本:因此,如果用户 A 使用参数执行脚本JOHN_DOE
(例如:-d JOHN_DOE
)并且用户 B 使用参数执行脚本-d ANNA_DOE
,则它运行不会有任何问题,但如果用户B 尝试使用JOHN_DOE
参数来执行它,而脚本的第一个实例尚未完成运行,则不允许用户 B 运行它。
有没有正确的方法来实现这一目标?
答案1
诸如此类的工具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
使脚本可执行(如果您调用它lockeg
then chmod a+x lockeg
),然后运行它
./lockeg -d JOHN_DOE
答案2
这取决于你所说的“适当”是什么意思;-)。如果您的意思是“简单”和(相对)“便携”,那么您可以:
如果每个合法参数也是一个合法文件名,您可以简单地创建空文件用作锁定文件。当然,您必须确保创建锁定文件和检查其存在之间没有间隙,但如果您有一个“适当的”shell,则不需flock
要这样做(并且有些系统不附带它);你可以简单地使用set -C
指示任何 Bourne shell不是使用 .redirect 重定向输出时覆盖现有文件>
。
例如:
#/bin/sh
# Your paramter.
param="${1?no parameter given}"
# Disallow overwriting files with '>'
set -C
# This will fail if the lockfile exists and create it if it doesn't.
# ':' is a no-op, the output of which is re-directed.
: >"${TMPDIR:-/tmp}/$param.lock"
#
# Do stuff ...
#
我所说的“正确”是指set -C
使用以下方法实现的 shellopen
系统调用的O_EXCL
标志,大多数 shell,包括重击, 做。大多数操作系统,包括Linux,保证对open
设置O_EXCL
了标志的调用是原子的——除非要打开的文件驻留在网络文件系统上。
如果有合法的参数不是也是合法的文件名,您可以简单地散列它们。
答案3
您可以使用一个包含每个用户及其允许的参数的文件,检查用户名,并在不匹配时退出脚本。