ハードリンクを保持してディレクトリをコピーする方法は?


40

共通のファイルがあるディレクトリを別のパーティションに移動する方法は?

/mnt/Xハードリンクでファイルを共有するディレクトリでパーティションがマウントされていると仮定しましょう。そのようなディレクトリを別のパーティションに移動する方法は、/mnt/Yそれらのハードリンクを保存することです。

「ハードリンクとファイルを共有するディレクトリ」とはどういう意味ですか?

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

具体的には、ファイルの合計サイズが10Gで、各ファイルに10個のハードリンクがあると仮定します。問題は、10Gを使用して宛先に移動する方法です(100Gでコピーしてから重複排除を実行することについて誰かが言うかもしれません-私が尋ねているものではありません)

回答:


29

最初の答え:GNU Way

GNUはcp -a、できるだけ多くの構造とメタデータを再帰的に保存します。ソースディレクトリ内のファイル間のハードリンクはそこに含まれています。の他のすべての機能を-a使用せずにハードリンク保存を選択するには、を使用します--preserve=links

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst

3
tarで+ 1、cpでgnu固有の引数を使用する場合は-1。
-WhyNotHugo

あなたは1つで3つの答えを与えました。それらを別々にコメントしたり評価したりできるように、それらを3つに分割できますか?(ヒント: - 「CP -a」とは、例えば後述の「タール」と「PAX」のために、さらに2つの追加は1つだけを残して、これを編集することができます。)
グジェゴシWierzowiecki

1
@GrzegorzWierzowiecki分割完了
アランカレー

6
@Hugo:GNU固有の引数を標準ツールに使用しても何も問題はありません。GNUバージョンは最近の事実上の標準であり、プリインストールされていない場合でも、GNUツールをインストールすることは一般的な慣行でした(私はいつもそうでした-ソラリスや* bsdバージョンよりも優れていました) 、それらは異なる* nix間の一貫性を提供しました)。GNUismを使用するが必須ではない場合は、GNUismを指摘することをお勧めします。また、Grzegorzは「Linuxではない」とは言わなかったので、それが彼が話している環境だと仮定するのは合理的です。
cas

1
@WhyNotHugo:POSIXはどのように「より標準的なのでしょうか?」POSIXは、私たちがいる場所をもたらしたものです。Windows NT以降のすべてのWindowsバージョンがPOSIXに完全に準拠していることをご存知ですか?POSIXファイルI / O関数を使用する場合、パスの長さには255文字の制限があり、役に立たなくなります。Solaris、Irix、HP-UXはすべてPOSIXに準拠していますが、ツールへのすべての引数は異なります(tarなど)。cp -aは、GNUコピーを置換したいcpバージョンの最小要件です。
ヨハネスオーバーマン

37

rsyncが持っている-H--hard-links、このためのオプションを、そして停止して再起動することができるという通常のrsyncの利点があり、かつ効率的に前回の実行後に/中に変更されたすべてのファイルを扱うために再実行されるように。

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

rsyncmanページを読んで、-Hを検索してください。特定の警告については、さらに詳細があります。


2
私はチェックしました-それは動作します。
グジェゴシWierzowiecki

うん、わかってる。バックアップスクリプトで何年も使用しています。また、あなたの質問のようにファイルシステム間でファイルを移動します。
cas

rsyncは、ファイルリストの作成時にメモリのゴブを使用します。「ファイルリストの作成」を何時間も続けた後、16 GBのメモリがいっぱいになり、何もコピーされずに保釈されました。YMMV。
msc

2
From man rsyncrsync 3.0.0以降、使用される再帰アルゴリズムは、以前よりも少ないメモリを使用し、最初のいくつかのディレクトリのスキャンが完了した後に転送を開始する増分スキャンになりました。このインクリメンタルスキャンは再帰アルゴリズムにのみ影響し、非再帰的転送は変更しません。また、転送の両端が少なくともバージョン3.0.0である場合にのみ可能です。 両方に注意し、この改善されたアルゴリズム--delete-before--delete-after無効にしてください。
cas

また、rsync非常に便利ですが、すべての仕事に最適なツールとは限りません。最近では、スナップショットとzfs sendそれらを作成できるようにZFSデータセットを使用することを好みます。ほとんどの場合、非ZFSファイルシステムでrsyncを使用します。 btrfs同様のスナップショット+送信機能があります。
cas

14

3番目の答え:POSIX Way

POSIXはtartarアーカイブ形式を標準化していますが、ユーティリティを標準化していません。tarアーカイブを操作するためのPOSIXユーティリティが呼び出さpaxれ、単一のプロセスでパックおよびアンパック操作を実行できるというボーナス機能があります。

mkdir dst
pax -rw src dst

10

2番目の答え:古代のUNIXの方法

ソースディレクトリにtarアーカイブを作成し、パイプで送信し、宛先ディレクトリに解凍します。

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)

1
チェック済み->動作します。ハードリンクが保持されます。
グジェゴシWierzowiecki

1
これが実際にハードリンクを保持する理由についての洞察はありますか?
ペテルフ

1
なぜならtarジャムハードリンク。GNU tarでは、少なくとも、次の--hard-dereference
コマンドを

私の場合、大きなディレクトリ階層(TimeMachineバックアップ)をコピーしようとすると、tarはいくつかのハードリンクを保持しましたが、場合によってはファイルを複製しました。これはtar x、ファイルがまだからパイプされているため、完全なファイルリストがないためだと思いますtar c。アーカイブ全体を保存してから解凍する場合は、おそらく大丈夫でしょう。誰かがその理論を確認できたらとてもうれしいです。
msc

10

ソース:http : //www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

正確なコピーを作成するために必要なのは

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/

上記のrsyncに関するコメントを参照してください。
msc

1
これにより、ACL、拡張属性などがコピーされないと思われます。Linuxバージョンには、これらを保持するための-Aおよび-Xオプションもありますが、MacOSでは運が悪いと思います。
エドワードフォーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.