rsyncを使用してディレクトリツリーを複製し、ファイルへのハードリンクを作成するにはどうすればよいですか?


23

時々、サーバー上のデータファイルに対していくつかの大きな移行の変更を実行する必要があり、これを行うための良い方法を探しています。ルートデータフォルダーからディレクトリ構造を複製するためにrsyncを使用して、すべての元のファイル(一部はかなり大きい)へのハードリンクを作成することを考えていました。移行先のツリーでは、移行が必要なファイルのみを上書きできます。最終的に、2つのmv操作で古いファイルから新しいファイルに安全に切り替えることができます。

ただし、これを行うためにrsyncを取得することはできません。私は試した

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

しかし、ファイルへのハードリンクを作成する代わりに、rsyncはそれらを完全にコピーします。同じソースとリンク先のディレクトリを使用して問題がありますか?

回答:


21

rsync は強力なツールですが、残念ながら、そのパス名のいくつかについて奇妙にうるさいです。

場合$DATA(それが始まるすなわち、絶対パスである/)、次いで、使用する正しいコマンドラインです。

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[さて、ちょっとrsync奇妙なことについてはさておき。/ソース引数に追加された末尾に注意してください。これは、ソースディレクトリ自体ではなく、ソースディレクトリの内容を操作するように指示rsyncします。(これにはまだ末尾が含まれていないと仮定します。)この場合、コンテンツを操作するため、末尾に。を追加します。$DATA//

一方、$DATA相対パスである場合(つまり、aで始まらない場合/)、Sean Rのコメント--link-destはバングオンです:link-destパスは宛先パスに関連して解釈されるため、次を使用します。

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

編集

最後に、パスが絶対パスであるか相対パスrsyncであるか$DATAは関係ないため、2番目に指定したコマンドラインは絶対パスであるかどうかに関係なく機能するはずbasenameです。


1
スラッシュが欠けているだけで、誰がそれを考えていただろうか...素敵な説明をありがとう!
ジャンフィリップペレット

このいただきありがとうございます、私は次のように、いくつかの増分バックアップの手順に従ってみました、この1と、この癖の一切の言及を見つけることができませんでした。これが、実際にファイルがハードリンクされていることを確認した唯一のことでした。参照カウントが> 1であり、inode番号が次と同じであることを確認しますls -ilah
-Walf

私に記載RELPATH()関数と一緒にこれを使用unix.stackexchange.com/a/85068/57414バックアップ$SOURCEにディレクトリを$TARGETこのようなDIRSOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
ネイサンS.ワトソン- Haighの


7

--link-destオプションは、現在のディレクトリではなく、宛先ディレクトリにrsync関連しています。だからあなたが欲しいのは:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp

おっと、私はベース名を意味しました。元々はディレクトリ名でした。
ショーンレイフシュナイダー

1
マニュアルページには、--link-destオプションがrelativeの場合、ターゲットディレクトリに相対であると記載されています。私の場合は絶対です。ターゲットディレクトリに相対させても、この動作はしません。
ジャンフィリップペレット

7

rsync他のツールよりもこれを行うのが難しいことがわかります。の正解rsyncはSteven Monai'sですが、これを行う最も簡単な方法は、次の有効なオプションがないシステムcp -alまたはpax -rwlシステムで使用-lすることですcp

pax -rwl $DATA $DATA/../upgrade_tmp

または

cp -al $DATA/ $DATA/../upgrade_tmp/

4

わたしにはできる:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

rsyncバージョン3.1.0を使用します。

から:

-ハードリンク

転送でハードリンクファイルを探すようにrsyncに指示します。このオプションを使用しない場合、転送中のハードリンクファイルは個別のファイルとして扱われます。

--link-dest = DIR

変更されていないファイルは、DIRから宛先ディレクトリにハードリンクされます。ファイルをリンクするには、保存されているすべての属性(アクセス許可、所有権など)が同じである必要があります


2
コードスニペットだけでは不十分です。その機能と理由を説明してください。
ペテルは、モニカを復活させると

--hard-links転送でハードリンクファイルを探すようにrsyncに指示します。このオプションなしでは、転送中のハードリンクファイルは個別のファイルであるかのように扱われます。 --link-dest = DIR変更されていないファイルは、DIRから宛先ディレクトリにハードリンクされます。ファイルをリンクするには、保存されているすべての属性(アクセス許可、所有権など)が同じである必要があります。
アレクサンダーフェドロフ

1
素晴らしい。ありがとうございました。実際、私はあなたの答えを「低品質」キューで見つけました。それは、あなたの答えを削除すべきか否かについて投票があったことを意味します。しかし、削除の危険性は、適切にフォーマットされた「人間」の回答をしようとする理由であるだけでなく、賛成票を集めたい場合にも大いに役立ちます。
ペテルはモニカを

2

次のリンク試すことができますhttp://www.lessfs.com/wordpress/それが仕事であるCOW時間と空間を節約します(書き込み上のコピー)


lessfsは非常に興味深いですが、非常に実験的でもあります。まだ実稼働での使用にはお勧めしません。
mattdm

2

最初に、宛先にのみディレクトリを作成します。

rsync -av --include '*/' --exclude '*' /source/ /destination/

次に、ファイルのみをハードリンクします。

cd /source
find . -type f -exec ln -v {} /destination/{} \;

おかげで-実際、pax上記のコメントで示したように使用することもできます。
ジャンフィリップペレット

1

オプション-Hを使用して、ハードリンクを保持し、マンページを読みます。


1
-Hは機能しません。ソースツリーに保持するハードリンクはありません。コピー内のすべてのファイルが元のファイルにハードリンクされているソースツリーの単純なコピーが必要です。私の元の質問で申し訳ありませんが不明確でした…
ジャンフィリップペレット

「マンページを読む」は答えですか?:-)
meduz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.