スレッドセーフな「sed」

スレッドセーフな「sed」

sedを使用してユーザー入力に従ってファイルを変更するシェル/Pythonスクリプトがある場合、2人のユーザーが同時にまたはほぼ同時に同じスクリプトを実行します。また、"sed"スレッドは安全ですか?それとも、最初のスレッドによって開かれたfile_descriptorがとにかくファイルをロックするために使用されるため、問題にならない可能性がありますか?ありがとう

ベストアンサー1

ひどい用語については議論しません。しかし、そうです。 GNU sedおよび対応する(「in-place」)フラグはファイルが実際には変更されない-iため、追加のロックなしで同時に複数のプロセスで安全に使用できます。sedただし、出力を一時ファイルにリダイレクトし、すべてがうまくいくと、一時rename(2)ファイルを元のファイルに移動(移動)してrename(2)原子性を確保します。

$ strace sed -i s/o/e/g foo.txt
open("foo.txt", O_RDONLY)               = 3
...
open("./sedDe80VL", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
...
read(3, "foo\n", 4096)                  = 4
...
write(4, "fee\n", 4)                    = 4
read(3, "", 4096)                       = 0
...
close(3)                                = 0
close(4)                                = 0
rename("./sedDe80VL", "foo.txt")        = 0

常にfoo.txtソースファイル全体または処理されたファイル全体が参照され、それらの間には何も参照されません。

メモ:

これは、他のプロセスが編集を完了するのを待たずに、複数のプロセスがファイルの編集を開始する状況を処理できません。この場合、最後に「勝利」したプロセスのみが完了します(つまり、他のプロセスで行われた変更は削除されます)。これはデータの整合性の問題ではなく、プロセス間のより高いレベルの調整なしでは処理できません。ファイルを盲目的にロックすると、デッドロックが発生します。

現在、GNU sed は標準ファイル権限を新しい inode にコピーしますが、ACL と拡張属性はコピーしません。sed -iこれらのファイルに使用すると、すべての追加のメタデータが失われます。 IMHO これはバグや制限ではなく機能に近いです。

perl -i仕組みはsed -i以前のバージョンとは大きく異なります5.28。まず、ファイルの一時コピーを作成し、元のファイルに切り取り、出力をそのファイルにリダイレクトします。これにより、元のinode番号と追加のメタデータが保持されますが、プロセスが中断されperl -iたりperl -i、複数のプロセスが同時にファイルを編集したりすると、ファイルの内容が完全に削除されます。より議論する、元の犯罪(今後改善)と変更ログperl5280delta

おすすめ記事