根据参数锁定 bash 脚本?

根据参数锁定 bash 脚本?

我试图找到一种根据给定参数锁定脚本的方法,但未能成功找到正确的答案。

我想要实现的是防止另一个用户基于某些参数运行脚本:因此,如果用户 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

使脚本可执行(如果您调用它lockegthen 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

您可以使用一个包含每个用户及其允许的参数的文件,检查用户名,并在不匹配时退出脚本。

相关内容