shellスクリプトはファイルロック機能を実現します。


1.背景
複数のプロセスが同じデータを実行する可能性がある場合、これらのプロセスは他のプロセスがデータを破損しないように動作しないことを保証する必要があります。通常、このようなプロセスは「ファイルをロックする」というファイルを使って、他のプロセスに自分が実行していることを伝えます。そのファイルが存在することを検出したら、同じデータを操作するプロセスがあると思います。このような問題は、プロセスが誤って死亡しました。そのロックファイルを整理していないと、ユーザーが手動で掃除するしかないです。
2.flockについて
flockはファイル全体に対する推奨ロックです。つまり、プロセスが一つのファイルにロックをかけていると、他のプロセスが分かります。提案性錠はプロセスの遵守を強要しない。)一番いいのは、最初のパラメータはファイルのディスクリプタです。このファイルのディスクリプタが閉じられている間、ロックは自動的に解除されます。プロセスが終了すると、すべてのファイル記述子が閉じられます。
3.shellでflockシステム呼び出しを実現するコマンドは、次の2つのフォーマットがあります。

flock [-sxon] [-w timeout] lockfile [-c] command...
flock [-sxun] [-w timeout] fd
オプションとパラメータ:
-s,--sharred:共有鍵を取得して、あるファイルに向けられているFDに共有ロックを設定して、ロックを解除していない時間内に、他のプロセスはこのファイルに向けられているFDに独占錠を設定する要求に失敗しました。他のプロセスはこのファイルに向けられているFDに共有ロックを設定する要求を試みました。成功します。
-x,-e,--exclusive:一つの列の鍵を取得します。または書き込みロックと呼ばれます。標準項目です。
-u,--unlock:手動でロックを解除します。一般的には必要ではありません。FDがオフされると、システムは自動的にロックを解除します。このパラメータはスクリプトコマンドの一部に非同期で実行されます。一部は同期で実行されます。
-n、--nb、--nonblock:ブロックモードではなく、ロックを取得して失敗した場合、待ち時間ではなく1を返します。
-w,--wait,--timeout seconds:ブロッキングタイムアウトを設定し,設定した秒数を超えるとブロッキングモードを終了し,1に戻り,後のステートメントを実行し続けます。
-o、--close:commandを実行する前に設定ロックのFDをオフにして、commandのサブプロセスをロックしないようにするという意味です。
-c.--command command:shellではその後の文を実行します。
4.shellでは、スクリプトの繰り返し実行を避けるために、それをロックします。
Linuxのルーチンcrontabはタイミングよくスクリプトを実行しますが、スクリプトの実行時間はコントロールできない場合があります。スクリプトの実行時間が長いと、前回のタスクのスクリプトがまだ終わっていないかもしれません。次のタスクのスクリプトがまた始まります。このような状況では、いくつかの合併問題が発生する可能性があります。深刻な場合は、汚れたデータ/パフォーマンスのボトルネックの悪循環が発生します。
flockを使って列を作ることで、この問題を回避できます。もし一つのプロセスが彼の列にロックをかけたら、他のプロセスはロックをかけられなくなります。タイムアウトを待つか、すぐに戻るかを選択できます。テストの例は以下の通りです。
4.1実行スクリプトの作成

#cat /scripts/shell/file_lock.sh
#!/bin/bash
# Description: test for file flock
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo ""
echo "----------------------------------"

echo "start at `date '+%Y-%m-%d %H:%M:%S'` ..."

sleep 140s

echo "finished at `date '+%Y-%m-%d %H:%M:%S'` ..."

4.2タイミングタスクを作成する:テストシートのロック

#crontab -e
* * * * * flock -xn /dev/shm/test.lock -c "sh /scripts/shell/file_lock.sh > /root/stdout.log"
このスクリプトは分間に一回実行され、出力情報をstdout.logに書き込みます。
 
出力ログを見ると以下の通りです。

----------------------------------
start at 2014-04-10 10:23:01 ...            #
finish at 2014-04-10 10:25:21 ...           #
 
 
----------------------------------
start at 2014-04-10 10:26:01 ...            #10:27:00 10:28:00 , , 10:26:00
finish at 2014-04-10 10:28:21 ...
4.3テストシートのロックに加え、タイムアウト待ち

* * * * * flock -x -w 20 /dev/shm/test.lock -c "sh /scripts/shell/file_lock.sh > /root/stdout.log"
ログ出力情報を表示:

----------------------------------
start at 2014-04-10 10:29:01 ...
finish at 2014-04-10 10:31:21 ...
 
----------------------------------
start at 2014-04-10 10:31:21 ...    #10:31:00 20 , , ,
finish at 2014-04-10 10:33:41 ...