특정 파일 목록 만 재 동기화하는 방법은 무엇입니까?


95

원격 서버로 푸시하고 싶은 다양한 하위 디렉토리에 약 50 개 정도의 파일이 있습니다. 나는 rsync가 --include-from 옵션을 사용하여 나를 위해 이것을 할 수 있다고 생각했습니다. --exclude = "*"옵션이 없으면 디렉토리의 모든 파일이 동기화되고 옵션을 사용하면 파일이 동기화되지 않습니다.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

처음에는 건조한 상태로 실행 중이며 0.0.0.0은 분명히 원격 서버의 IP로 대체됩니다. rsync_include.txt의 내용은 업로드하려는 파일에 대한 상대 경로의 새 줄로 구분 된 목록입니다.

월요일 아침에 나를 피하는 더 좋은 방법이 있습니까?

답변:


3

편집 : 아래 Josip Rodin의 대답이 더 좋습니다. 저거 사용하세요!

특정 파일 목록을 찾고 있다면 대신 명령 줄에 직접 넣는 것이 더 쉬울 수 있습니다.

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

그러나 이것은 목록이 너무 길지 않아 명령 줄 길이가 문제가되고 rsync_include.txt파일에 실제 경로 만 포함되어 있다고 가정합니다 (예 : 주석 및 정규 표현식 없음).


9
불행히도 이것은 큰 목록이나 이름에 공백이있는 파일에서는 작동하지 않습니다.
Wes Modes

3
[인수 목록이 너무 깁니다.]
Dankó Dávid 2017

기본적으로 xargs는 stdin의 인수를 명령 줄 끝에 추가합니다. rsync가 대상이 될 마지막 인수가 필요하기 때문에 작동하지 않습니다. xargs의 일부 버전은 대신 명령 줄 중간에 인수를 선택적으로 삽입 할 수 있습니다. 파일 목록이 길 때 rsync를 두 번 이상 실행할 수 있다는 점을 염두에 두지 않는 한 작동합니다. 어쨌든 rsync --files-from아마도 더 쉽고 안정적인 솔루션 일 것입니다. :)
Lassi

Wes Hardaker : "Josip Rodin의 답변"에 대한 편집 및 참조가 실제로 Rodin이 편집 한 @atp 답변 을 참조 합니까?
Seamus

234

--files-from원하는 것을 정확하게 수행 하는 플래그 가 있습니다. 에서 man rsync:

--files-from=FILE

이 옵션을 사용하면 전송할 파일의 정확한 목록을 지정할 수 있습니다 (지정된 FILE에서 읽은대로 또는 표준 입력의 경우-). 또한 지정된 파일과 디렉토리 만 더 쉽게 전송할 수 있도록 rsync의 기본 동작을 조정합니다.

  • --relative (-R) 옵션이 내포되어 파일의 각 항목에 대해 지정된 경로 정보를 보존합니다 (해제하려면 --no-relative 또는 --no-R 사용).

  • --dirs (-d) 옵션이 내포되어있어 시끄럽게 건너 뛰지 않고 대상 목록에 지정된 디렉토리를 만듭니다 (해제하려면 --no-dirs 또는 --no-d 사용).

  • --archive (-a) 옵션의 동작은 --recursive (-r)를 의미하지 않으므로 원하는 경우 명시 적으로 지정하십시오.

  • 이러한 부작용은 rsync의 기본 상태를 변경하므로 명령 줄에서 --files-from 옵션의 위치는 다른 옵션이 구문 분석되는 방식에 영향을주지 않습니다 (예 : -a는 --files- 전후에 동일하게 작동 함). --no-R 및 기타 모든 옵션과 마찬가지로).

FILE에서 읽은 파일 이름은 모두 소스 디렉토리에 상대적입니다. 모든 선행 슬래시가 제거되고 ".."참조는 소스 디렉토리보다 더 높을 수 없습니다. 예를 들어 다음 명령을 사용하십시오.

rsync -a --files-from=/tmp/foo /usr remote:/backup

/ tmp / foo에 문자열 "bin"(또는 "/ bin")이 포함 된 경우 / usr / bin 디렉토리는 원격 호스트에서 / backup / bin으로 생성됩니다. "bin /"(후행 슬래시 참고)이 포함 된 경우 디렉토리의 즉각적인 내용도 전송됩니다 (파일에 명시 적으로 언급 할 필요없이 2.6.4 버전에서 시작됨). 두 경우 모두 -r 옵션이 활성화 된 경우 해당 dir의 전체 계층도 전송됩니다 (-r은 -a에 의해 암시되지 않으므로 --files-from과 함께 명시 적으로 지정되어야합니다). 또한 (기본적으로 활성화 됨) --relative 옵션의 효과는 파일에서 읽은 경로 정보 만 복제하는 것입니다. 소스 스펙 경로 (이 경우 / usr)를 강제로 복제하지는 않습니다. .

또한 파일 앞에 "host :"를 지정하면 로컬 호스트 대신 원격 호스트에서 --files-from 파일을 읽을 수 있습니다 (호스트는 전송의 한쪽 끝과 일치해야 함). 바로 가기로 "전송의 원격 끝 사용"을 의미하는 ":"접두사 만 지정할 수 있습니다. 예를 들면 :

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

이렇게하면 원격 "src"호스트에있는 / path / file-list 파일에 지정된 모든 파일이 복사됩니다.

--iconv 및 --protect-args 옵션이 지정되고 --files-from 파일 이름이 한 호스트에서 다른 호스트로 전송되는 경우 파일 이름은 보내는 호스트의 문자 집합에서 수신 호스트의 문자 집합으로 변환됩니다.

참고 : --files-from 입력에서 파일 목록을 정렬하면 인접한 항목간에 공유되는 경로 요소를 다시 방문하지 않아도되므로 rsync를보다 효율적으로 수행 할 수 있습니다. 입력이 정렬되지 않은 경우 일부 경로 요소 (묵시적인 디렉터리)가 여러 번 스캔 될 수 있으며 rsync는 파일 목록 요소로 전환 된 후 결국 중복을 해제합니다.


23
rsync -av --files-from=file-list . target/현재 디렉토리에서 파일을 복사하는 경우와 같이 나열된 파일이있는 디렉토리를 지정해야합니다 .
Nicolas Mattia

7
예, 다시 말하지만 The filenames that are read from the FILE are all relative to the source dir.
atp

아, 놓 쳤어, 미안!
Nicolas Mattia

1
파일의 파일에 ..rsync로 시작 ..하는 것이 있으면 나에게 다음과 같은 오류 가 표시되는 것처럼 보이는 rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory경우 (이 경우 "test"dir에서 실행되고 존재하는 "../subdir/test.txt"를 지정하려고합니다.
Michael

--files-from인수를 명시적인 포함 및 제외 목록과 결합 할 수 있으며 , 추가 된 목록의 파일이 --files-from기존 제외 규칙 을 재정 의하여 파일에 나타날 경우 포함되도록할까요?
highsciguy

13

--files-from=절대 경로를 그대로 유지하려면 매개 변수에 후행 슬래시가 필요합니다. 따라서 명령은 다음과 같습니다.

rsync -av --files-from=/path/to/file / /tmp/

이것은 많은 수의 파일이 있고 모든 파일을 x 경로에 복사하려는 것처럼 수행 될 수 있습니다. 따라서 파일을 찾고 아래와 같은 파일에 출력을 던집니다.

find /var/* -name *.log > file

9

기록을 위해 위의 답변 중 하나를 제외하고는 도움이되지 않았습니다. 요약하면 다음 --files-from=중 하나를 사용하여 백업 작업을 수행 할 수 있습니다.

 rsync -aSvuc`cat rsync-src-files` / mnt / d / rsync_test /

또는

rsync -aSvuc --recursive --files-from = rsync-src-files. / mnt / d / rsync_test /

이전 명령은 rsync-src-files아래에서 자세히 설명 할 파일의 내용 옆에 자명 합니다. 이제 후자의 버전을 사용하려면 다음 네 가지주의 사항에 유의해야합니다.

  1. 둘 다 --files-from소스 디렉토리 를 지정해야합니다.
  2. 명시 적으로 지정해야 --recursive합니다.
  3. 이 파일 rsync-src-files은 사용자가 만든 파일이며이 테스트를 위해 src 디렉토리에 배치되었습니다.
  4. rsyn-src-files복사 할 파일 및 폴더를 포함하고 소스 디렉토리에 상대적 가져옵니다. 중요 : 파일에 후행 공백이나 빈 줄이 없는지 확인하십시오. 아래의 예에는 세 줄이 아닌 두 줄만 있습니다 (우연히 파악). 의 내용 rsynch-src-files:

folderName1
folderName2


3

비슷한 작업이 있습니다 : 주어진 날짜 이후에 수정 된 모든 파일을 rsync하지만 일부 디렉토리는 제외합니다. 하나의 라이너 올인원 스타일을 만드는 것이 어려웠 기 때문에 문제를 작은 조각으로 나누었습니다. 마지막 해결책:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

먼저 find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". 이름 패턴을 제외 regex하기 위해 find줄 에 추가하려고했지만 Linux (Mint) 솔기의 내 취향은 find. 정규식 버전을 시도했습니다. 원하는대로 작동하지 않습니다. 그래서 나는 egrep -v패턴 쉬운 방법을 제외하는 옵션으로 끝납니다 . 나는 /.cache 또는 /.configrsync같은 디렉토리와 내가 명시 적으로 명명 한 다른 디렉토리를 복사하지 않습니다 .


1
나는 당신이 이것을 bash하나의 라이너 로 바꾸기 위해 프로세스 대체를 사용할 수 있다고 믿는다 .rsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
phk

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

통사론: rsync <file_/_folder_list> <source> <target>

폴더 이름 (여기서는 후행 포함 /; 예 Cancer - Evolution/)은 폴더 목록 파일 (예 : cm_folder_list_test)에 있습니다.

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

이러한 후행을 포함하지 않으면 /rsync 대상 폴더가 생성되지만 비어 있습니다.

이러한 폴더 이름은 나머지 경로 ( /home/victoria/Mail/2_RESEARCH - NEWS)에 추가되어 rsync에 대한 전체 폴더 경로를 제공합니다. 예 : /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

--files-from=..., NOT --include-from=... 도 사용해야합니다 .

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(내 BASH 스크립트에서 $IN다음과 같이 변수 를 정의 했습니다.)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

사용 된 rsync 옵션 :

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

이 대답은 질문에 대한 직접적인 대답이 아닙니다. 그러나 문제에 가장 적합한 솔루션을 파악하는 데 도움이됩니다.

문제를 분석 할 때 디버그 옵션을 활성화해야합니다. -vv

그런 다음 rsync는 어떤 파일이 어떤 패턴에 의해 포함되거나 제외되는지 출력합니다.

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

내가 가진 모든 것이 디렉토리 목록 일 때이 답변 중 어느 것도 나를 위해 일하지 않았습니다 . 그런 다음 해결책을 발견했습니다! 당신은 추가 할 필요 -r--files-from하기 때문에 -a이 시나리오 (누가 알고 있었다?!)의 재귀되지 않습니다.

rsync -aruRP --files-from=directory.list . ../new/location

파일에 "dir"을 나열하는 경우 -r / —recursive를 지정해야합니다. "dir /"을 나열하면 그렇지 않습니다.
lbutlr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.