rsync -Lを「反転」する方法は?

rsync -Lを「反転」する方法は?

rsyncフラグに関するドキュメントから-L

-L、--copy-linksシンボリックリンクを参照されたファイル/ディレクトリに変換します。

この質問は、元の用途を「反転」する方法についてですrsync -L ...


簡単で具体的な例では、「逆方向」が何を意味するかを説明するのが最も簡単です。

設定

次のディレクトリ/tmp/SOURCE/合計があるとします/tmp/TARGET/

$ /usr/bin/tree -aF /tmp/SOURCE/ /tmp/TARGET/
/tmp/SOURCE/
├── A.d/
│   ├── w
│   └── x
├── B.d/
│   └── z
├── C.d/
│   ├── w -> ../A.d/w
│   └── y -> ../A.d/x
└── D.l -> B.d/
/tmp/TARGET/

次の詳細に特別な注意を払ってください。

  • の内容は、/tmp/SOURCE/C.d一般ファイルを指す相対記号リンクです/tmp/SOURCE/A.d
    • シンボリックリンクのデフォルト名/tmp/SOURCE/C.d/wとその参照は同じです。
    • /tmp/SOURCE/C.d/yシンボリックリンクのデフォルト名(例:)は、y参照するオブジェクトxのデフォルト名(例:)とは異なります。
  • /tmp/SOURCE/D.l相対シンボリックリンクです/tmp/SOURCE/B.d
  • /tmp/TARGET/現在空です。

この初期状態では、この記事のタイトルに記載されているコマンドを実行します。「反転」するコマンドのタイプ(以下で詳しく説明されています):

$ rsync -L -a /tmp/SOURCE/C.d /tmp/SOURCE/D.l /tmp/TARGET

このコマンドを実行すると、/tmp/TARGET/次のように表示されます。

$ /usr/bin/tree -aF /tmp/TARGET/
/tmp/TARGET/
├── C.d/
│   ├── w
│   └── y
└── D.l/
    └── z

/tmp/SOURCE両方と相対/tmp/TARGETパスの下にあるという事実に特別な注意を払ってください。

C.d/w
C.d/y
D.l/z

存在する場合、以下のみが/tmp/TARGET「本当の」パスです。 「実際のパス」とは、大まかに$P言うと、その出力が(またはより正確には)であるreadlink -f $Pことを意味します。例えば$P${P:a}

$ readlink -f /tmp/TARGET/C.d/w
/tmp/TARGET/C.d/w

しかし、

$ readlink -f /tmp/SOURCE/C.d/w
/tmp/SOURCE/A.d/w

質問

現在の状況では、前のrsync -Lコマンドを「反転」するということは、基本的に通常のファイルを/tmp/TARGET/そのコマンドにコピーすることを意味します。オリジナル下に/tmp/SOURCE、滞在する構造変わらず/tmp/SOURCE

具体的には、この「リバース転送」の後、下のシンボリックリンクは/tmp/SOURCEシンボリックリンクとして維持され、次のことを指す必要があります。正確に前と同じ参照です。

rsync -aL私は、最初に「順方向」転送を実行するために使用されたコマンドと、複雑さ/困難の点で比較できるこの「反転」を実行する方法を探しています。


この簡単な例の一つの欠点はとても簡単です人々は問題を解決するために暴力を使用しようとする誘惑を受けます。例えば

$ rsync /tmp/TARGET/C.d/w /tmp/SOURCE/A.d
$ rsync /tmp/TARGET/C.d/y /tmp/SOURCE/A.d/x
$ rsync /tmp/TARGET/D.l/z /tmp/SOURCE/B.d

IOW、このような単純なケースでは、これらの無差別アプローチは、生のrsync -L転送を実行するよりもはるかに難しくありません。しかし、一般に、無差別代入戦略は、生の転送よりも実行するのがはるかに困難です。

この例は、ソースホストと宛先ホストが同じであるため、あまりにも単純化されています。 一般的に言えばそうではありません。したがって、この例のこの機能に依存するソリューションを避けてください。


FWIW、次のスクリプトは上記のおもちゃの例の設定を生成します。

BASEDIR=/tmp/test1

# uncomment the following line before running this script a second time
# rm -rf $BASEDIR/SOURCE $BASEDIR/TARGET

mkdir -p $BASEDIR/SOURCE/{A,B,C}.d $BASEDIR/TARGET
touch $BASEDIR/SOURCE/{A.d/{w,x},B.d/z}
ln -s ../A.d/w $BASEDIR/SOURCE/C.d/w
ln -s ../A.d/x $BASEDIR/SOURCE/C.d/y
ln -s B.d $BASEDIR/SOURCE/D.l

ベストアンサー1

ディレクトリを参照するときにrsyncがリモートのシンボリックリンクを妨げないようにするいくつかのオプションがありますが、ファイルのシンボリックリンクを実際のファイルに置き換えないオプションはないようです。

したがって、あなたができることは、最初にファイルの名前を変更したりファイルにリストしたりするなど、何らかの方法でSOURCEのファイルへのシンボリックリンクを保存し、次にrsyncを実行してディレクトリシンボリックリンクを保存し、データの物理ファイルコピーからファイルシンボリックリンクを復元することです。復元されたシンボリックリンクに移動し、実際のファイルを削除します。潜在的なスクリプトは次のとおりです。

find /tmp/SOURCE -type l ! -xtype d -exec mv {} {}.lnk \;
cd /tmp/TARGET || exit
rsync -a -R --no-implied-dirs --keep-dirlinks . /tmp/SOURCE/
find /tmp/SOURCE -type l ! -xtype d |
while read fname
do base=${fname%.lnk}
   cp "$base" "$fname" 
   mv "$fname" "$base"
done

奇妙なファイル名を正しく処理するようにします。これが必要かどうかはわかりませんが、-R --no-implied-dirs試してみましょう。

おすすめ記事