Linuxにおけるディレクトリ内容の再帰的移動

Linuxにおけるディレクトリ内容の再帰的移動に対する実務上の答えは「mvはディレクトリ自体を指定すれば配下をまとめて移動でき、内容だけを移す場合の*はdotfileを含みません。対象をfindで列挙し、移動先の空き容量・重複名・mount境界を確認し、backupまたはsnapshotを取ってから少量ずつ移します。」です。ここでは同一filesystemのrenameと別filesystemへのcopy-and-removeで障害時の性質が異なる前提を明示し、初回確認、sample実行、本番判定、元へ戻す条件をそれぞれ独立させます。

目次

移動元・移動先とfilesystem境界を固定する

ディレクトリを再帰移動する前に、移動元と移動先のファイルシステム、空き容量、所有者、シンボリックリンクの扱いを確認します。rsyncのdry-runとitemize出力で対象を固定し、コピー後の件数とハッシュが一致してから切り替えます。元ディレクトリの削除は別工程として承認後に行います。

  • find source -mindepth 1 -maxdepth 1 -printでdotfileを含む直下を確認する
  • findmnt -T sourceとfindmnt -T destinationでfilesystemを比較する
  • df -hとdf -iで容量とinode余裕を確認する
  • 移動先に同名file、symlink、権限差がないか照合する

trailing slashとdotfileで変わる対象を読む

  • アスタリスクでdotfileを落とす
  • 同名directoryへmergeされる動作を見落とす
  • 別filesystemをatomic renameと思い込む
  • 開かれたDBfileを稼働中に移す
  • ACL、xattr、hard linkを保持しないcopyへ置き換える

同一filesystemのmvと段階rsyncを使い分ける

ディレクトリ自体を移す

printf '%s\n' '移動元:'
find ./project -maxdepth 2 -print
printf '%s\n' '移動先:'
ls -ld -- ./archive
mv -i -- ./project ./archive/

-iは上書き前に確認します。非対話の自動処理ではprompt待ちになるため、事前に重複を検査し、終了コードを確認する設計へ変えます。

内容だけをdotfile込みで候補表示

find ./source -mindepth 1 -maxdepth 1 -print

shellの*は通常、名前がドットで始まる項目を展開しません。findの一覧を保存し、.envや.gitなど移動してよいdotfileか個別に判断します。

別filesystemはrsyncで段階移行

rsync -aHAXni --numeric-ids -- ./source/ ./destination/
# itemized changeを保存し、対象・件数・metadata方針を承認する
rsync -aHAXi --numeric-ids -- ./source/ ./destination/
# 実copy後、itemized outputが空になることを再確認する
rsync -aHAXni --numeric-ids -- ./source/ ./destination/

-nはdry-run、-iは変更候補のitemize表示です。最初の確認から両方を併用し、ACLやxattrを使わない環境では保存要件とoption対応を確認します。実コピー後に件数とhashを確認しても、元データの削除は別の承認済み作業に分けます。

重複候補を確認

find ./source -mindepth 1 -maxdepth 1 -printf '%f\n' | sort > source.names
find ./destination -mindepth 1 -maxdepth 1 -printf '%f\n' | sort > destination.names
comm -12 source.names destination.names

同名項目が出たら機械的に上書きせず、内容と所有者を比較します。この確認ファイルは作業記録へ保存し、終了後に規程に沿って扱います。

既存名との衝突を移行前に洗い出す

mvに再帰オプションは不要で、ディレクトリをoperandにすれば全体を扱います。ただしsource/*はshell展開でありdotfileを落とします。source/.*を足す方法は.や..、shell差、重複の問題を招くため、内容だけの移行にはfindやrsyncで対象を明示します。cross-filesystemではコピー後に元を除く動作になり、途中失敗で両側に一部が残る可能性があります。

itemized dry runを承認記録にする

移動はパスを変えるため、サービス、symlink、設定、backup jobから見えなくなる重大な変更です。maintenance windowを取り、書き込みを止めるか整合性の取れるsnapshotを準備します。最初に読み取り一覧とdry-runを保存し、小さいsubsetで移動後の起動確認を行います。異常時は同一filesystemなら元の親へmvで戻し、別filesystemなら検証済みcopyを元位置へ戻して所有者、ACL、xattrを照合します。未確認の再帰削除で整理しません。

file hashとmetadataをcopy後に照合する

findの件数とdu –bytesの概算を両側で比較し、重要ファイルはsha256sum manifestを作って照合します。所有者とmodeはstat、ACLはgetfacl、xattrはgetfattrの利用可否を環境で確認します。サービスから新pathを読み、監視、backup、log rotationが追随したことを確認して初めて完了とします。

source削除へ進めるparity gateを定義する

同一filesystemのrenameはmvで短時間に完了できますが、別filesystemではrsync -aHAXのdry-run、実copy、再dry-run、切替の順に進めます。rsyncは成功0、syntax/usage 1、partial transfer 23/24などを返すため、0以外を一括で成功扱いしません。

-niで実copyと同じ候補を表示する

rsync -aHAXni --numeric-ids -- ./source/ ./destination/
printf 'dry_run_status=%s\n' "$?"

変更あり・差分なし・転送errorを分類する

  • copy候補承認済み:dry-runのitemized changeを承認し、実copy後の再dry-runが空で件数とhashが一致する
  • 転送差分なし:sourceが空でも意図した空directoryかpath誤りかを判定し、勝手にdestinationを空へ揃えない
  • 容量・権限・metadata error:permission/ACL/xattr非対応、vanished file、容量不足はrsync statusとstderrを残して切替を止める

source末尾slashは内容、slashなしはdirectory自体という差があります。-aだけではhard link、ACL、xattrをすべて含まないため、-HAXの対応filesystemと必要権限を確認します。–deleteは移行確認の既定にしません。

hardlink・ACL・xattrを含むfixtureで試す

( cd ./source && find . -xdev -type f -print0 | sort -z | xargs -0 -r sha256sum ) > source.sha256
( cd ./destination && find . -xdev -type f -print0 | sort -z | xargs -0 -r sha256sum ) > destination.sha256
cmp -- source.sha256 destination.sha256

通常file、dotfile、symlink、hard link、ACL、xattr、空directory、更新中fileをtest treeへ置きます。SHA-256 manifestはregular fileの内容を照合するためのものです。directory構造、symlink先、hard link関係、owner・mode、ACL、xattrはfind、stat、getfacl、getfattrで別に照合し、open fileを持つserviceの切替時刻も確認します。

rsyncの最初の確認は-nだけでなく-iを併用し、実copyでも同じitemized形式を残します。copy後の再dry-run、hash、ACL・xattr照合がそろうまで、移動元の削除は独立した未実施工程として扱います。

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次