構造を維持しながら、あるディレクトリの下のすべてのシンボリックリンクを別のディレクトリに再帰的にコピーする簡単な方法はありますか?

構造を維持しながら、あるディレクトリの下のすべてのシンボリックリンクを別のディレクトリに再帰的にコピーする簡単な方法はありますか?

~/tmp/foo/サブディレクトリ、ファイル、およびシンボリックリンクでいっぱいのディレクトリがあります。

$ tree ~/tmp/foo/
tmp/foo/
├── eggs
│   ├── baz
│   │   └── link3.txt -> /home/me/file3.txt
│   └── link2.txt -> /home/me/file2.txt
├── hello.txt
├── link1.txt -> /home/me/file1.txt
└── spam
    ├── link4.txt -> /home/me/file4.txt
    └── link5.txt -> /home/me/file5.txt

3 directories, 6 files

~/tmp/foo/asファイル(私が使用したものと同じ)の下のすべてのシンボリックリンクを別の(空ではない)ディレクトリに再帰的にcp -rHコピーしたいと思います~/bar/。これを行う簡単な方法はありますか?

私は以下を試しました:

find ~/tmp/foo/ -type l -print | rsync -avzL --files-from=- ~/tmp/foo/ ~/tmp/bar/

しかし、これは失敗しました。

答え1

検索には結果にパスプレフィックスが含まれているため、検索パスがrsyncパスに基づいて「.」であることを確認してください。また、同様の間違いを犯した場合に警告するrsyncのエラーメッセージを読んでください。

rsync: link_stat "/test/a/a/1/3.txt" failed: No such file or directory (2)

以下は私に役立つ例です。

mkdir test
cd test
mkdir a b 
cd a
mkdir 1
echo 1 > 1/2.txt
ln -s 1/2.txt 1/3.txt
tree ../
../
├── a
│   └── 1
│       ├── 2.txt
│       └── 3.txt -> a/1/2.txt
└── b

それから

find . -type l | rsync -av --files-from=- ./ ../b/
building file list ... done
./
1/
1/3.txt -> a/1/2.txt

sent 99 bytes  received 25 bytes  248.00 bytes/sec
total size is 9  speedup is 0.07
tree ../
../
├── a
│   └── 1
│       ├── 2.txt
│       └── 3.txt -> a/1/2.txt
└── b
    └── 1
        └── 3.txt -> a/1/2.txt

4 directories, 3 files

失敗のために-Lコマンド(a / 1 / 2.txtをb / 1 / 2.txtに変更)が機能しないという意味であれば...なぜそのようなことが起こるのかわかりませんが、解決したいと思います。mount --bind --make-slave

答え2

通常のファイル foo/hello.txt をコピーしても問題ない場合は、次のものを使用できます。

$ cp -RLv ~/foo/ ~/bar/

この-Lスイッチは、cpツリーで見つかったすべてのシンボリックリンクを逆参照するように指示します。これは、-Hコマンドライン引数でのみシンボリックリンクを逆参照するように指示するswitchとは異なります。

ただし、リンクとシンボリックリンクを具体的にコピーする場合は、コマンドライン提案をより複雑にすることが唯一の考えです。

$ ( cd ~/tmp/foo/ ; find -mindepth 1 '(' -type l -o -type d ')' -print | cut -b 3- ) | rsync -avzL --files-from=- ~/tmp/foo/ ~/tmp/bar/

アイデアは次のとおりです。

  • パラメータはfindシンボリックリンクとディレクトリを返し、次のレベルへのパスを返すように変更されました(したがって、「.」エントリは返されません)。

  • rsync--files-from=パラメーターには相対パスが必要です。そのため、find次のようにソースディレクトリからコマンドを強制的に実行する必要がありました。( cd ~/tmp/foo ; find )

  • 出力からcut -b 3-プレフィックスを削除します。./find

関連情報