web-dev-qa-db-ja.com

Linux:大きなファイルツリーを移動し、コピー中にファイルを削除する方法(後ではない)

クリアからecryptfsまでディスクをインプレースで暗号化したいと思います(ブートディスクではなく、大量のデータファイルを含むディスクのみ)。

次の構造を作成しました。

  /mnt/
   clear/ # the source files
   cipher/ # the ecryptfs ciphertext directory
   mounted.clear/ # the mounted ecryptfs directory

次のようなことをしたいのですが:mv /mnt/clear/* /mnt/mounted.clear/

問題は、これはファイルシステム間の移動であるため、mvは最初に各引数をコピーしてからリンクを解除することです( ここ を参照)。このディスクには、/mnt/clearの下のサブディレクトリの一部を複製するのに十分な空き領域がありません。

mv --delete-during引数(または同様のもの)があればいいのですが、ありません(GNU coreutils 8.3にはありません:))その他easyのアイデア?私はそれを行うための簡単なスクリプトを書くことができますが、私が使用できるより簡単なソリューション/ユーティリティがある場合はそうではありません。

2
Yaniv Aknin

rsyncのこのオプション:

_--remove-source-files_
これは、rsyncに、転送の一部であり、受信側で正常に複製されたファイル(非ディレクトリを意味する)を送信側から削除するように指示します。

_rsync -av --remove-source-files /mnt/clear/ /mnt/mounted.clear
_

私のテストでは、ツールがファイルを最後ではなくその場で削除することが示されています。

ノート:

  • _/_の後のスラッシュ(_/mnt/clear_)は重要です。
  • 「正常に複製された」とは、問題が発生した場合でも、何も失うことはないことを意味します。
  • 別の手順でディレクトリを削除する必要があります。 _find /mnt/clear/ ! -type d_を使用して、古い非ディレクトリがないことを確認します。

rsyncを使用できない場合は、tarの次のオプションを検討してください。

_--remove-files_
ファイルをアーカイブに追加した後、ディスクからファイルを削除します。

_cd /mnt/mounted.clear/ &&
( cd /mnt/clear/ && tar -vc --remove-files * ) | tar -x
_

私のテストでは、最初のtarがファイルを最後ではなく、その場で削除することを示しています。ただし、落とし穴があります。

  • 最初のtarは、ファイルが宛先ディレクトリに安全に書き込まれるまで、ファイルの削除を延期する必要があります。ありえない。ツールは、パイプの残りの部分で何が起こっているかを知ることができません。ファイルを処理するとすぐに、ファイルを削除します。 2番目のtarが遅れ、データがパイプバッファに蓄積され、最初のtarがファイルを熱心に削除する場合があります。このような場合、何らかの理由で2番目のtarが失敗すると、パイプが壊れ、バッファリングされたコンテンツ(すでに削除されたファイルから)が失われます。バッファを減らすと(たとえば、stdbufを使用して)損傷を最小限に抑えることができますが、ソリューションを完全に安全にすることができるかどうかはわかりません。

    意図的にcd … && tar … | ( cd … && tar … )を使用しませんでした。このバージョンでは、最初のcdが処理して何かを削除した後に、2番目のtarの障害が発生する可能性があります。元のコードでは、最初のcdが実行される前に、両方のtarコマンドが成功する必要があります。

  • _*_は、_._で始まるファイルと一致しません。


追記:

  • 私のテストでは、ファイルがディレクトリリストから遅れて消えました。つまり、rsyncまたはtarがファイルを処理した後、数秒(場合によっては1分)です。私はBtrfsを使用していますが、これがその癖だと思います。
2