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
시도해 보겠습니다.
답변2
rsync
나는 심볼릭 링크 디렉토리를 그대로 유지하는 . --keep-dirlinks
() 옵션 을 직접 사용할 수 없다고 생각 -K
하지만 심볼릭 링크 파일은 여전히 덮어쓰게 됩니다.
내가 찾을 수 있는 가장 가까운 해결책은 작은( bash
) 스크립트 였습니다.
( cd TARGET && find . -type f -print0 | sed 's!^./!!' ) |
while IFS= read -d $'\0' -r f
do
s=$(readlink -f SOURCE/"$f")
rsync -a TARGET/"$f" "${s:-f}"
done
이번에 TARGET
는 각 파일이 파일에 저장되고 해당 파일의 심볼릭 링크 대상이 확인되어 SOURCE
해당 rsync
파일에 직접 적용됩니다.