我有一个~/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 路径,因为 find 在结果中包含路径前缀。另请阅读 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
取消引用树中找到的所有符号链接。它与 switch 不同-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