Jul 03, 2009

ファイルのオーバーライド

通常のパイプ動作するフィルタコマンドでは 元ファイルを直接オーバライドできない。
例えば sort (1) の -o オプションの様に 元ファイルのオーバライド指定ができる (この動作をスポンジ動作というらしい)もの以外での処理について。

一番簡単で誰でも思いつくのが一時ファイルを利用するやりかた。

$ command < foo.dat > foo.new 
$ mv foo.new foo.dat
この方法だと command の実行中に割込が発生したりすると 一時ファイルが残ってしまい美しくない。

$ cat foo.dat | ( sleep 1; command > foo.dat)
この方法だと sleep (1) の時間がうっとおしく、 データ量や command の速度などによって失敗する場合もありうる。

$ (rm foo.dat; command > foo.dat) < foo.dat
若干判りづらいのだがこれで確実に成功する。
先行する rm (1) は必須である。 rm (1) がない場合は外側のシェルが '<' により O_RDONLYopen (2) するファイルと 内側のシェルが '>' により O_RDONLY|O_TRUNCopen (2) するファイルの inode が等しいので OS は同一ファイルと見做し、 command の標準入力は O_TRUC により truncate されたファイルとなってしまう。
対して rm (1) がある場合は外側のシェルが O_RDONLYopen (2) するファイルと 内側のシェルが O_RDONLY|O_TRUNCopen (2) するファイルの inode が異なるので O_TRUNC による truncate は影響を受けない。

Edit this entry...

wikieditish message: Ready to edit this entry.
















A quick preview will be rendered here when you click "Preview" button.