두 시스템 간에 디렉터리를 동기화하고 싶습니다. 더 흥미롭게 만들기 위해 동기화는 한 방향으로만 수행될 수 있습니다. 즉:
- 원본 디렉터리에서 파일을 삭제하면 이전에 전송된 파일이 대상 디렉터리에서도 삭제되어야 합니다.
- 대상 디렉터리에서 삭제된 파일은 원본 디렉터리에서 삭제되어서는 안 됩니다.
- 부분적으로 전송된 파일(예: 네트워크 문제로 인해)은 다음 동기화 시 완료되어야 합니다.
- 원본 디렉터리의 새 파일을 대상 디렉터리로 전송해야 합니다.
- 대상 디렉터리에서 삭제된 파일은 재전송되지 않을 수 있습니다.
즉, 소스 시스템은 기본적으로 마스터 역할을 가지지만 대상 시스템에서 삭제된 파일은 강제로 복구되지 않습니다.
두 Linux 시스템 모두 rsync/ssh/scp를 사용할 수 있습니다.
소스 디렉터리의 새 파일은 mtime을 사용하여 탐지할 수 있는 방식으로 생성됩니다. 예:
if mtime(file) > date-of-last-sync then: it is a new file that needs to be transfered
또한 소스 디렉터리의 기존 파일은 변경되지 않습니다. 즉, 동기화 시 이미 (완전히) 전송된 파일의 차이점을 확인할 필요가 없습니다.
답변1
원격 파일 시스템을 전송된 콘텐츠의 데이터 소스로 사용할 계획이 없다면 이전에 성공적으로 전송된 파일을 외부에서 추적하고 향후 전송에서 제외해야 합니다.
rsync
다음을 기준으로 파일을 포함하거나 제외할 수 있습니다.무늬전송 시 특정 파일 목록을 포함할 수 있도록 파일에 저장합니다. 그러면 이 목록은 향후 전송에서 제외됩니다.
#!/usr/bin/env bash
set -e
track_dir=~/.track_xfer
inc_file="$track_dir/include_files"
exc_file="$track_dir/exclude_files"
xfer_dir=~/testrsync
xfer_dest=~/testrsync_dest
mkdir -p "$track_dir"
touch $exc_file
cd "$xfer_dir"
# find files and create rsync filter list
find . -type f -print0 | perl -e '
$/="\0";
while (<>){
chomp;
$_ =~ s!^\.!!; # remove leading .
$f = quotemeta; # quote special chars
$f =~ s!\\/!/!g; # fix quoted paths `/`
print $f."\n";
}' > "$inc_file"
# Run the rsync
rsync -va --delete --exclude-from "$exc_file" --include-from "$inc_file" "$xfer_dir/" "$xfer_dest"
# Add the included/transferred files to the exclusion list
cat "$inc_file" "$exc_file" > "$exc_file".tmp
sort "$exc_file".tmp | uniq > "$exc_file"
좀 더 구체적인 정규식 참조가 필요할 수도 있지만 rsync
Perlquotemeta
기능 및 교체가 내 마음에 떠오르는 첫 번째 간단한 솔루션입니다.
주요 문제는 파일 이름의 특수 문자를 처리하는 것입니다. 이름의 새 줄이나 탭 및 기타 이상한 항목을 처리하려면 perl
패턴 목록이 포함된(또는 무엇이든) 구문 분석하고 생성하는 데 더 많은 작업을 투자해야 합니다. 전송되는 파일의 이름을 간단한 문자 집합으로 제한할 수 있다면 이 단계에 대해 너무 걱정할 필요가 없습니다. perl
가장 일반적인 정규식 문자를 극복하는 데 도움이 되는 절충 솔루션은 다음과 같습니다.
rsync
전체 디렉터리를 자체적으로 가져오는 대신 포함 목록을 사용하는 이유는 후속 제외 목록에 대해 정의된/완전한 파일 목록을 갖기 위함입니다. 전송된 파일 rsync
이나 의 출력을 구문 분석하여 --log-file=FILE
동일한 결과를 얻을 수도 있지만 조금 어려운 것 같습니다.
답변2
Rsync는 원하는 작업을 정확하게 수행합니다 rsync -a --delete
( -x
예: selinux의 경우 xattrs가 필요한 경우 추가).
Rsync는 소스의 파일을 절대 삭제하지 않지만, --delete
소스에 존재하지 않는 대상의 파일은 모두 삭제합니다.
증분 업데이트 메커니즘을 통해 부분적으로 전송된 파일을 업데이트합니다. AFAIR rsync는 먼저 mtime(+ 파일 크기)을 확인하고 불일치가 있는 경우 지문 채취 및 증분 업데이트만 완료합니다.
답변3
모든 질문에 대한 답변을 제공하므로 매뉴얼 페이지를 읽어 보십시오. 이 명령을 실행 man rsync
하면 매뉴얼 페이지가 표시됩니다.
rsync는 파일이 변경되지 않았는지 확인합니다. 이는 매우 효율적이며 전송의 rsync 시간을 크게 늦추지 않았습니다. 마지막 실행 직후 rsync 실행 시간을 측정하여 필요한 시간을 추정할 수 있습니다.
rsync는 단방향 동기화이며 소스를 변경하지 않습니다. 소스 파일을 읽을 수만 있고 쓰기 권한은 없는 사용자 ID를 안전하게 사용할 수 있습니다. 그러나 반드시 그럴 필요는 없습니다.
rsync를 다시 실행하면 부분적으로 완료된 전송이 재개됩니다.
rsync는 삭제 옵션 중 하나를 사용하는 경우에만 대상의 파일을 삭제합니다.
편집: 대상 디렉터리에서 삭제된 파일이 재전송되지 않도록 하려면 해당 파일에 대한 제외 목록을 만들어야 합니다. 업데이트된 경우에도 전송에서 제외됩니다. 또는 파일을 삭제하는 대신 파일을 자르고 해당 --update
플래그를 사용할 수 있습니다. 잘린 후 업데이트된 파일이 복사됩니다.
증분 tar 백업을 사용하면 요구 사항을 더 잘 충족할 수 있습니다. 하나의 tar의 출력은 SSH 연결을 통해 다른 tar로 파이프될 수 있습니다. 그러면 마지막 백업 이후 생성되거나 수정된 모든 파일이 선택되지만 다른 파일은 전송되지 않습니다.