
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。
答え2
複数の並列操作に対して同じファイルにsed -iを使用することはお勧めできませんが、必要に応じて...
動作させるパターンは次のとおりです。 シグナル。
機能的なスレッド認識方式で同じファイルで sed -i への非同期呼び出しを許可するには、次のようにします。コンサルティングロック。
flock theSharedFile sed -i s/"userInput1"/"$userInput2"/g theSharedFile
FlockはSharedFileにアドバイザリロックを作成し、ロックが解除されると(SharedFileで実行されている他のクラスタがない場合)、残りのパラメータを使用してsedコマンドが実行されます。
2人の他のユーザーが同時に実行すると、2人目のユーザーは前のユーザーが完了するのを待ちます。このように完全に機能的でスレッドセーフな方法になります。すべての「ユーザー」変更は削除または上書きされません。
推奨ロックなので、クラスターにのみ適しており、いかなる種類のデッドロックも発生しません。ファイルを読んでいる人はロックされません。ファイルが大きい場合、ロックを待つプロセスにかなりの時間がかかることがあります。
現在のロックを一覧表示できます。lslocks
これが誰かに役立つことを願っています。時間をいただきありがとうございます。