sed出力を同じ入力ファイルにリダイレクトすると、マシンが応答しなくなるのはなぜですか?


13

sed大きなファイル(100 MB)のいくつかのキーワードを置き換えようとしていました。-i(インプレース)オプションを知らなかったので、私の最初の試みは次のようにリダイレクトすることでした:

sed 's/original/edited/g' file.log >> file.log

その後、PCが停止し、キーボード入力がほとんどなくなりました。私は別のコンソールが試みたCtrl+ Alt+ F1が、ゆっくりと、ユーザー名を入力した後、それはあまりにも停止しました。キーボードなしで、私の唯一のオプションは、マシンをハードウェアリセットすることでした。ログイン後、file.logが約8 GBであることがわかりました。

私は本当にそのコマンドの実行がシステムを非常に無反応にすることができた理由と、アラートをトリガーして問題のあるプロセスを殺すためのメカニズムがシステムレベルに存在する場合、本当に理解したいと思いますか?


7
これはシングルコアマシンですか?これが現代のコンピュータをひざまずかせたのは非常に奇妙に思えます。はい、ディスクがいっぱいになりました。はい、コアの1つを100%使い果たしました。しかし、完全なクラッシュですか?
テルドン

そのファイルについて何か特別なことはありますか?これが問題でない場合は、その内容をpastebinに投稿できますか?
セルギーKolodyazhnyy 16

また、あなたの記憶の量は何ですか?の出力を提供していただけfree -h ますか?
セルギーコロディアズニー16

ファイルを変更するときに、そもそもストリームエディターを使用するのはなぜですか?副作用のex -sc '%s/original/edited/ge|x' file.logないUNIXの慣用的な方法で、必要なことを行う必要がありますsed -i
デビッドオンガロ

(人々が提供している方法のいずれかによって)正しく実行している場合でも、アクティブなプロセスに属するログファイルに対してこの種の処理を行うのは危険です。
Random832 16

回答:


10

既に述べた>>ように、ファイルに追加するので、sedコマンドはそこに座って、出力したばかりの行を読み取り、さらに出力します。ファイルをその場で置き換えたい場合は、>それでも機能しませんが、sed-iオプションを知っています。これは間違いなく必要なオプションです。

ただし、ストリームとして読み込んでいるファイルに追加する必要があり、このパスを1回だけ実行したい場合spongeは、moreutilsパッケージからの使用を検討してください。

sed 's/original/edited/g' file.log | sponge >> file.log

spongeEOFまでstdinからメモリに読み込み、すべての内容をstdoutにダンプします。そのためsed、ファイルの終わりに到達し、読み込みを停止して閉じ、スポンジが追加を開始します。


2
sponge知っておくと便利なユーティリティですが、sedすでに-iオプションがあります-i[SUFFIX], --in-place[=SUFFIX], edit files in place (makes backup if SUFFIX supplied)
ジョシュアテイラー

@ JoshuaTaylor、OPはを使用>>していました>。確かに、OPは-iポストで具体的に言及しており、これよりもはるかに一般的なユースケースのように見えますが、OPが投稿した特定の操作は、あなたが本当にそれはあなたがやりたいことだと確信しています。
ymbirtt 16

1
受け入れられた答えのキーだったので、私はここでそれを言及しました。といえ、スポンジについて学ぶことができて本当にうれしいです。それは私のツールボックスの新しいツールであり、そのためだけの賛成に値します。
ジョシュアテイラー

1
あ!そうですか。それを少し明確にするために、答えを微調整します。あなたが楽しんだ場合にも、sponge、を見てみましょうvipemoreutilsあなたが必要と知っていたことがないもので満たさちょうど魔法のパッケージです
ymbirtt

18

あなたのsedコマンドは、それが追加されたファイルを読み込むしようとしていました。ファイルの終わりに達することはありませんが、多くのCPU時間を消費しようとします。^ C(割り込み電流プロセス)が発明されたのはそのためです。


^ Cはオプションではなかったと思います... HALTに行きました。つまり、カーソルが点滅せず、スタックしました。
EKons 16

18

読み込んでいるファイルに追加し直すことは、良いアイデアではありません。ファイルが増え続けるためです。本当にファイルに書き戻したい場合は、-iフラグを使用する必要があります。

sed -i 's/original/edited/g' file.log

または、変更を行う前にバックアップを作成する場合は、ファイルサフィックスを-iフラグに追加できます。

sed -i.bak 's/original/edited/g' file.log

これにより、ファイルが作成され、file.log.bak変更が行われます。あなたが読んでいるファイルにプログラマースラングで呼び出すデータ競合を追加しようとすることで、そこで行われたことを行います。 。これは、マシンが停止した理由でもあります。


1
それはないとしても、アドレスのOPの質問ませんので、私は、これが受け入れ答えで驚いている"I really would like to understand why the execution of that command was able to make the system so unresponsive, and if mechanisms exist at the system level to trigger alerts and kill the offending process?"
スティーブ

@Steveなぜ停止したのかについてはお話ししましたが、2番目の部分については正しいです。私はこれに対する答えを知らないので、私はそれに対処しませんでした。チャットでのディスカッションの後にコマンドを広範囲にテストし、マシンとオペレーティングシステムが異なるとまったく異なる結果になりました。例:アーチを備えたマシンでは、ファイルが永久に成長するだけで、マシンが応答しなくなることはありません。私のUbuntuマシンでは、プロセスを強制終了する機会なしに質問者と同じ結果が得られました。Ubuntu VMで同じものをテストしている2台目のマシンも同様に停止しました。
Videonauth 16

strace反対側の全プロセスのうち、didtnは私のマシンと他のユーザーのマシンで結果とこれを再現します。応答しないアプリケーションを強制終了できるメカニズムは確かにありますが、マシンが応答しない場合は、リセットするオプションが1つしかありません。私はまだこれについてテストしていますが、説明されている動作の原因を完全に理解する前に、質問のこの部分に対処することはできません。
Videonauth 16

おそらく、IOを優先する別のスケジューラーのようなカーネル構成の違い、またはシステム間のディスク/ファイルシステムドライバーの違いです。皆さんが行った調査を見るのは良いことです。それは良い情報です。
スティーブ

別のデータポイントに興味がある場合; これをかなり小さなファイルのCentOSマシンで試しましたが、以下のスポンジソリューションとまったく同じことをしました。小さなファイルsedでは、ハンドルを保持するのではなく、すべてのものをメモリにバッファリングしてから閉じると想像します。OPのように、〜100MBのファイルを使用すると、無制限に成長しますが、マシンを破壊しませんでした。
-ymbirtt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.