私は端末を使用して、次のように複数のコマンドの出力を同時に同じファイルにパイプします。
cmd1 | tee -a /tmp/file
cmd2 | tee -a /tmp/file
cmd3 | tee -a /tmp/file
使っても安全ですか?この方法を使用すると、データの損失や読み取り/書き込み権限の問題がありますか?
編集する:出力ミックスに満足しています。すべてがファイルに書き込まれていることを確認したいと思います。両方のコマンドが同時にファイルに出力を書き込もうとすると、競合が発生しますか?
答え1
append
tee with()モードを使用すると、追加の操作-a
がないファイルシステム(NFSなど)以外のデータ損失のリスクはありません。append
モードでは、tee
フラグ付きのファイルを開きますO_APPEND
。
$ echo 1 | strace tee -a /tmp/file 2>&1 | grep open | grep /tmp/file
openat(AT_FDCWD, "/tmp/file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
からman 2 openat
:
O_APPEND The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.
重要な文章はファイルオフセットの変更および書き込み操作は、単一の原子ステップで実行されます。。write()
インスタンスに関係なく、各呼び出しはtee
ファイルオフセットをファイルの末尾にアトミックに配置し、データを書き込むことを保証します。
マニュアルopenat
ページでは、この使用パターンはNFSファイルシステムでは安全ではないと述べています(前述のように):
O_APPEND may lead to corrupted files on NFS filesystems if more than one process appends data to a file at once. This is be‐ cause NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition.