与えられたパラメータに基づいてスクリプトをロックする方法を見つけようとしていますが、正しい答えが見つかりませんでした。
私が達成したいのは、他のユーザーが特定のパラメータに基づいてスクリプトを実行するのを防ぐことです。したがって、ユーザーAがパラメーターJOHN_DOE
(例えば-d JOHN_DOE
)を使用してスクリプトを実行し、ユーザーBがパラメーターを使用してスクリプトを実行する-d ANNA_DOE
と、問題なく実行されます。ユーザーユーザーBJOHN_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
)chmod a+x lockeg
実行します。
./lockeg -d JOHN_DOE
答え2
「適切さ」が何を意味するかによって異なります;-)。 「シンプル」と(相対的に)「ポータブル」を意味する場合は、次のことができます。
もし各正当なパラメータは正当なファイル名でもあります。単に空のファイルを作成してロックファイルとして使用できます。もちろん、ロックファイルを作成することとその存在を確認することの間にギャップがないことを確認する必要がありますが、「適切な」シェルがある場合はこれをflock
行う必要はありません(そして一部のシステムにはこのシェルが付属していません)。 ;簡単に使えますset -C
Bourne シェルに指示します。いいえ.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
「正しい」とは、次のように実装されたシェルを意味します。open
O_EXCL
以下を含むほとんどのシェルのシステムコールフラグ吹く、する。以下を含むほとんどのオペレーティングシステムLinux、開こうとしているファイルがネットワークファイルシステムに存在しない限り、フラグが設定された呼び出しがアトミックであることを保証しますopen
。O_EXCL
法的パラメータがある場合いいえまた、有効なファイル名なので簡単にハッシュできます。
答え3
各ユーザーと許可されたパラメーターを含むファイルを使用し、ユーザー名を確認し、一致するものがない場合はスクリプトを終了できます。