구조를 유지하면서 한 디렉터리 아래의 모든 심볼릭 링크를 다른 디렉터리로 재귀적으로 복사하는 쉬운 방법이 있습니까?

구조를 유지하면서 한 디렉터리 아래의 모든 심볼릭 링크를 다른 디렉터리로 재귀적으로 복사하는 쉬운 방법이 있습니까?

~/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

관련 정보