2013年8月19日に、Randal L. Schwartzはこのシェルスクリプトを投稿しました。これは、Linux上で、「[スクリプト]の1つのインスタンスのみが実行され、競合状態やロックファイルのクリーンアップなし」を保証することを目的としています:
#!/bin/sh
# randal_l_schwartz_001.sh
(
if ! flock -n -x 0
then
echo "$$ cannot get flock"
exit 0
fi
echo "$$ start"
sleep 10 # for testing. put the real task here
echo "$$ end"
) < $0
宣伝どおりに動作するようです:
$ ./randal_l_schwartz_001.sh & ./randal_l_schwartz_001.sh
[1] 11863
11863 start
11864 cannot get flock
$ 11863 end
[1]+ Done ./randal_l_schwartz_001.sh
$
ここに私が理解していることがあります:
- スクリプト
<は、自身のコンテンツのコピー(から$0)を0サブシェルのSTDIN(ファイル記述子)にリダイレクト()します。 - サブシェル内で、スクリプトは
flock -n -xファイル記述子で非ブロッキングの排他ロック()を取得しようとします0。- その試みが失敗した場合、サブシェルは終了します(他に何もすることがないため、メインスクリプトも終了します)。
- 代わりに試行が成功した場合、サブシェルは目的のタスクを実行します。
私の質問は次のとおりです。
- スクリプトがサブシェルによって継承されたファイル記述子に、たとえば他のファイルのコンテンツではなく、独自のコンテンツのコピーをリダイレクトする必要があるのはなぜですか?(別のファイルからリダイレクトして、上記のように再実行しようとしましたが、実行順序が変更されました。バックグラウンドタスクの前に非バックグラウンドタスクがロックを取得しました。
- とにかく、スクリプトが、サブシェルによって継承されたファイル記述子に、ファイルの内容のコピーをリダイレクトする必要があるのはなぜですか?
0あるシェルでファイル記述子の排他ロックを保持すると、別のシェルで実行されている同じスクリプトのコピーがファイル記述子の排他ロックを取得できなくなるのは0なぜですか?シェルは、(標準のファイルディスクリプタの独自の、独立したコピーを持っていない0、1と2、すなわちSTDIN、STDOUT、およびSTDERR)?