- GIDEON
- GIDEON STAFF BLOG
2012/11/01
ファイルのオーバーライド
通常のパイプ動作するフィルタコマンドでは
元ファイルを直接オーバライドできない。
例えば 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_RDONLY で open (2) するファイルと 内側のシェルが '>' により O_RDONLY|O_TRUNC で open (2) するファイルの inode が等しいので、 OS は同一ファイルと見做し command の標準入力は O_TRUC により truncate されたファイルとなってしまう。
対して rm (1) がある場合は、 外側のシェルが O_RDONLY で open (2) するファイルと、 内側のシェルが O_RDONLY|O_TRUNC で open (2) するファイルの inode が異なるので、 OS はそれぞれを違うファイルと見なすためである。