名前

flock - シェルスクリプト内からロックを管理する

書式

flock [options] file|directory command [arguments]

flock [options] file|directory -c command

flock [options] number

説明

このユーティリティーは、 シェルスクリプト内から、 あるいはコマンドラインから、 flock(2) を使ったロックを管理する。

上に示す 1 つめと 2 つめの実行形式は、 command の実行に関わるロックを保護する。 その方法は、 su(1) や newgrp(1) と同様である。 この際には、 指定された file または directory をロックする。 ファイルまたはディレクトリが存在していなければ、 (権限は適切に有している前提で) 生成される。 デフォルトで、 ロックを即座に取得できなかった場合、 flock は、 それが利用可能になるまで待機する。

3 つめの形式は、 ファイルディスクリプター番号 number で表されるファイルをオープンして利用する。 利用方法がどのようなものであるかは、 以降を参照のこと。

オプション

-c, --command command

ただ 1 つのコマンドを、 引数なしで -c を使ってシェルに受け渡す。

-E, --conflict-exit-code number

-n オプション指定時であって、 競合するロックが存在する場合の終了ステータスを指定する。 または、 -w オプション指定時であって、 タイムアウトが発生した場合の終了ステータスを指定する。 デフォルト値は 1 である。 number は 0 から 255 の範囲でなければならない。

-F, --no-fork

command の実行前にフォークを行わない。 処理実行時に、 この flock プロセスが command によって置き換えられ、 それが引き続いてロックの維持を行う。 このオプションは、 --close と同時に用いることはできない。 これを行ってしまうと、 ロック維持がすべてなくなってしまう。

-e, -x, --exclusive

排他的ロックを取得する。 これは書き込みロック (write lock) と呼ばれる場合もある。 これがデフォルトである。

-n, --nb, --nonblock

ロックが即座に取得できなかった場合は、 待機せず、 失敗して終了する。 終了ステータスについては -E オプションを参照のこと。

-o, --close

command の実行前に、 ロックが保持されているファイルディスクリプターを閉じる。 これは、 command が子プロセスを起動していて、 そのプロセスがロックを保持していないような場合に利用することができる。

-s, --shared

共有ロックを取得する。 これは読み込みロックと呼ばれる場合もある。

-u, --unlock

ロックを解除する。 普通この操作は必要ない。 ロックは、 ファイルが閉じられると、 自動的に解除されるからである。 ただし特定の場合には、 必要になることがある。 たとえば、 一連のコマンドグループから、 バックグラウンドプロセスが起動されていて、 そこではロックを保持したくないような場合である。

-w, --wait, --timeout seconds

seconds 秒以内にロックを取得できなかった場合には、 処理失敗とする。 10 進数による小数表現を行うことができる。 終了ステータスについては、 -E オプションを参照のこと。 seconds にゼロを指定すると、 --nonblock として解釈される。

--verbose

ロックの取得に要した時間や、 ロック取得ができなかった理由を表示する。

-h, --help

ヘルプを表示して終了する。

-V, --version

バージョンを表示して終了する。

終了ステータス

このコマンドは、 全般に <sysexits.h> の終了ステータスを利用する。 ただし -n-w を用いる場合は例外である。 その場合は、 ロック取得に失敗した際に、 -E オプションで指定された終了ステータス、 あるいはデフォルトでは 1 を返す。 -E により指定される終了ステータスの範囲は、 0 から 255 でなければならない。

command を実行する形式を利用し、 子プロセスが適切に実行された場合、 終了ステータスは、 そのコマンドが返すものとなる。

注意

flock はデッドロックを検出しない。 詳しくは flock(2) を参照のこと。

ファイルシステムの一部 (たとえば NFS や CIFS) には、 flock(2) の実装に制限があるため、 flock の処理が失敗する場合がある。 詳しくは flock(2), nfs(5), mount.cifs(8) を参照のこと。 マウントオプションによっては、 flock が常に失敗する場合がある。

以下の例において "shell> " はコマンドラインプロンプトである。

shell1> flock /tmp -c cat; shell2> flock -w .007 /tmp -c echo; /bin/echo $?

ディレクトリ /tmp に対して排他ロックを設定する。 このため 2 つめのコマンドは失敗する。

shell1> flock -s /tmp -c cat; shell2> flock -s -w .007 /tmp -c echo; /bin/echo $?

ディレクトリ /tmp に対して、 共有ロックを設定する。 2 つめのコマンドは失敗しない。 ここで排他ロックを設定していたら、 2 つめのコマンドは失敗する。

shell> flock -x local-lock-file echo 'a b c'

echo 'a b c' の実行前に、 排他ロック "local-lock-file" を取得する。

(; flock -n 9 || exit 1; # ... ロックの下でのコマンド実行 ...; ) 9>/var/lock/mylockfile

この形式は、 シェルスクリプト内で用いる際に便利である。 ファイルオープンに用いているモードは、 flock を気にかけなくて済む。 つまり、 >>> を用いれば、 ロックファイルが存在しない場合には、 ロックファイルが生成されるようになる。 ただし、 その際には書き込み権限がなければならない。 < を用いるなら、 そのファイルがすでに存在していることが必要だが、 読み込み権限だけがあればよい。

[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :

これは、 シェルスクリプト上で利用される定番のコードである。 ロックしたいシェルスクリプトの先頭に、 このコードを置けば、 初回の実行時に、 自動的にロックされる。 このシェルスクリプトにおいて、 変数 $FLOCKER が設定されていないのは、 まだ起動されていないということである。 そこで flock を起動して、 待機を行わない排他ロックを取得する (ロックファイルには、 このスクリプトファイル自体を用いる)。 その右側にある引数は、 その後に改めて実行される。 またこの変数 FLOCKER には、右辺が代入されるため、 再度実行されることがない。

shell> exec 4<>/var/lock/mylockfile; shell> flock -n 4

この形式は、 サブプロセスを実行することなく、 ファイルをロックできるので便利である。 シェルは、 ファイルディスクリプター 4 を使って、 ロックファイルの読み書きを行う。 flock はそのディスクリプターのロックに用いられる。

作者

著作権

Copyright (co 2003-2006 H. Peter Anvin. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

関連項目

flock(2)

バグ報告

バグ報告は、 以下にある issue トラッカーを利用すること。 <https://github.com/util-linux/util-linux/issues>.

入手方法

flock コマンドは util-linux パッケージの一部であり、 以下からダウンロードできる。 Linux Kernel Archive <https://www.kernel.org/pub/linux/utils/util-linux/>.