将父目录复制到子目录中而不出现无限循环

将父目录复制到子目录中而不出现无限循环

由于应用程序特定的原因,我需要将整个父目录复制到子目录中。例如,

cp -r ../ tmp/

这样做的问题是它陷入了无限循环,一遍又一遍地递归复制 tmp/ 的内容。

有很多方法可以解决这个问题,比如压缩目录并将其解压到 tmp 中,但我想知道是否有任何特别优雅/unixy 的解决方案。

(注:我使用的是 Apple OS/X)。

答案1

如果从父目录开始,则可以使用findGNU来执行此操作cp。假设您当前所在的目录(包含 的目录tmp)名为folder,并且该目录tmp为空,您可以运行

cd ..
find . -path ./folder/tmp -prune -o -type f -exec cp --parents -t folder/tmp {} +

这要求 find 列出下面的所有内容.(这是你的旧的..),如果它匹配则排除它./folder/tmp,否则如果它是一个文件,则将其传递给cp选项--parents(它告诉cp重建源层次结构)。

如果tmp已经有还需要复制的文件,则以下变体稍微少一点 Unix-y (因为它使用moreutils' sponge)但避免跳过以下内容tmp

cd ..
find . -type f -print0 | sponge | xargs -0 cp --parents -t folder/tmp

sponge您可以通过保存要复制到其他位置的文件中的文件列表来避免使用(但随后事情会变得不太优雅):

cd ..
find . -type f -print0 > /tmp/filelist
xargs -0 cp --parents -t folder/tmp < /tmp/filelist
rm /tmp/filelist

cp您可以通过使用以下方式来避免对 GNU 的要求cpio

cd ..
find . -type f -print0 > /tmp/filelist
cpio -pmd0 folder/tmp < /tmp/filelist
rm /tmp/filelist

或者

cd ..
find . -type f -print0 | sponge | cpio -pmd0 folder/tmp

如果tmp为空,您还可以避免以下要求moreutils

cd ..
find . -path ./folder/tmp -prune -o -type f -print0 | cpio -pmd0 folder/tmp

答案2

对于交互式使用,我对 mv 的类似情况进行了修改:

cd ..
mv * tmp

mv: cannot move ‘tmp’ to a subdirectory of itself, ‘tmp/tmp’

忽略该错误,其他所有内容都已移动:-P。与 cp 的工作原理不太一样,它会创建一个空的 tmp/tmp,这可能不是您想要的。

答案3

使用pax, 复制.subdir/tmp, 跳过subdir/tmp

mkdir -p subdir/tmp &&
  pax -rws'|^\./subdir/tmp/.*||' . subdir/tmp

或者,您可以执行以下操作:

mkdir -p subdir/tmp/subdir &&
  ln -s tmp subdir/tmp/subdir/tmp &&
  cp -a . subdir/tmp

subdir/tmp/subdir/tmp那么它就是一个指向自身的符号链接,将cp无法在其下创建任何内容。如果需要,您可以稍后将其替换为空目录。

相关内容