4

ディスク容量が不足している場合にファイルを切り捨てる危険を冒さずに、シェルスクリプトからファイルを書き換える方法は?

この便利な perl ワン ライナーは、test.txt というファイル内のすべての "foo" を "bar" に置き換えます。

perl -pi -e 's/foo/bar/g' test.txt

これは非常に便利ですが...

test.txt が存在するファイル システムのディスク容量が不足している場合、test.txt は 0 バイトのファイルに切り捨てられます。

この切り捨ての発生を回避するための簡単で競合状態のない方法はありますか?

test.txt ファイルを変更せずに残し、ファイル システムの容量が不足している場合にコマンドがエラーを返すようにしたいと考えています。

理想的には、追加のソフトウェアをインストールする必要なく (sed や perl などの「標準的な」UNIX ツールを超えて)、ソリューションをシェル スクリプトから簡単に使用できるようにする必要があります。

ありがとう!

4

2 に答える 2

4

通常、これは実行できません。スペース不足の状態は、インプレース編集のように見える一連のアクションに沿ってどこでも発生する可能性があることに注意してください。ファイルシステムがいっぱいになると、perl は元の状態を復元するために以前のアクションを元に戻すことができない場合があります。

スイッチを使用するより安全な方法-iは、空でないバックアップ サフィックスを使用することです

perl -pi.bak -e 's/foo/bar/g' test.txt

これにより、途中で問題が発生した場合でも、元のデータを保持できます。

close自分でロールしたい場合は、システムコールから返された値を確認してください。Linux のマニュアル ページに記載されているように、

の戻り値をチェックしないことはclose()よくあることですが、それでも重大なプログラミング エラーです。以前のwrite(2)操作でのエラーが最初に final で報告される可能性は十分にありclose()ます。ファイルを閉じるときに戻り値をチェックしないと、サイレントにデータが失われる可能性があります。これは特に、NFS とディスク クォータで確認できます。

人生の他のすべてと同様に、エラーの余地をもっと残してください。ディスクが安い。ソファのクッションからポケットの小銭を掘り出して、0.5 テラバイト程度を自分で買いに行きましょう。

于 2013-04-22T10:12:49.383 に答える
3

からperldoc perlrun:

-i[extension]

" " コンストラクトによって処理されるファイルをその<>場で編集することを指定します。これは、入力ファイルの名前を変更し、出力ファイルを元の名前で開き、その出力ファイルをprint()ステートメントのデフォルトとして選択することによって行われます。拡張子が指定されている場合は、古いファイルの名前を変更してバックアップ コピーを作成するために使用されます。次の規則に従います。

拡張子が指定されていない場合、バックアップは作成されず、現在のファイルが上書きされます。

[…]

言い換え:

  1. -iバックアップ ファイル名は、 -switch が指定されている場合は、その値から決定されます。
  2. 元のファイルの名前が新しいファイル名に変更され、スクリプト用に開かれます。名前の変更は、ほとんどのファイルシステムでアトミックです。
  3. 元のファイルの名前を持つファイルが書き込み用に開かれます。ファイルは長さ 0 で始まりますが、元のファイル (現在は別の名前になっています) と同一ではありません。
  4. スクリプトが終了した後、明示的なバックアップ拡張子が指定されていない場合、バックアップ ファイルは削除されます。その後、元のファイルは失われます。

システムのドライブ容量が不足すると、コピーも移動もされていない元のファイルではなく、新しいファイルが危険にさらされます (少なくとも inode のような概念を持つファイルシステムでは)。

于 2013-04-22T10:11:19.380 に答える