rsync: 여러 파일 형식을 제외하는 방법은 무엇입니까?

rsync: 여러 파일 형식을 제외하는 방법은 무엇입니까?

이것은 Catalina를 실행하는 Mac에서 bash를 사용하는 경우입니다.

이것은 작동합니다:

rsync -Pa --rsh="ssh -p 19991" --exclude '*.jpg' --exclude '*.mp4' pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

다음은 해당되지 않습니다.

rsync -Pa --rsh="ssh -p 19991" --exclude={'*.jpg', '*.mp4'} pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

rsync -Pa --rsh="ssh -p 19991" --exclude {'*.jpg', '*.mp4'} pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

출력은 다음과 같습니다.

building file list ...
rsync: link_stat "/Users/mnewman/*.mp4}" failed: No such file or directory (2)
rsync: link_stat "/Users/mnewman/pi@localhost:/home/pi/webcam" failed: No such file or directory (2)
0 files to consider
sent 29 bytes  received 20 bytes  98.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files could not be transferred (code 23) at /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54.120.1/rsync/main.c(996) [sender=2.6.9]

제외할 파일 형식 목록에 내가 뭘 잘못하고 있나요?

답변1

우선, 첫 번째 예제는 작동합니다. 이를 사용하는 데 어떤 문제가 있습니까?

정말로 그렇게 하고 싶지 않다면 --exclude=*.{jpg,mp4}(일부 쉘에서는)로 확장되는 를 시도해 보십시오 --exclude=*.jpg --exclude=*.mp4. 단, 다음 사항에 유의하십시오.

  1. 이것은쉘 기능~라고 불리는버팀대 확장. 그것은~ 아니다rsync 또는 rsync의 필터 규칙 기능입니다.

    rsync가 중괄호 자체를 사용할 것이라고 잘못 생각하는 경우 이는 쉽게 혼란스럽고 "놀라운" 동작으로 이어질 수 있습니다(중괄호를 사용하지도 않고 볼 수도 없고 아예 볼 수도 없습니다).

  2. 확장이 완료되었습니다~ 전에rsync가 실행됩니다. rsync는 다음과 같은 내용만 볼 수 있습니다. --exclude=*.mp4 왜냐하면현재 디렉터리에 해당 패턴과 일치하는 파일 이름이 없습니다.

  3. --exclude=*.mp4드물게 또는 일치하는 파일 이름이 있는 경우 --exclude=*.jpg중괄호 확장은 와일드카드 없이 정확한 파일 이름으로 확장됩니다.

예를 들어

$ mkdir /tmp/test
$ cd /tmp/test
$ echo rsync --exclude=*.{jpg,mp4}
rsync --exclude=*.jpg --exclude=*.mp4

지금까지는 아주 좋습니다... 하지만 실제로 중괄호 확장과 일치하는 파일 이름이 있으면 어떤 일이 발생하는지 살펴보세요.

$ touch -- --exclude=foo.jpg
$ touch -- --exclude=bar.mp4
$ touch -- --exclude=foobar.mp4
$ echo rsync --exclude=*.{jpg,mp4}
rsync --exclude=foo.jpg --exclude=bar.mp4 --exclude=foobar.mp4

많은 --exclude옵션을 입력하지 않는 더 좋은 방법은 배열과 printf를 사용하는 것입니다.

excludes=('*.mp4' '*.jpg')
rsync ...args... $([ "${#excludes[@]}" -gt 0 ] && printf -- "--exclude='%s' " "${excludes[@]}") ...more args...

그러면 다음과 같은 명령줄이 생성됩니다.

rsync ...args... --exclude='*.mp4' --exclude='*.jpg'  ...more args...

더 나은 방법은 배열 및 프로세스 대체를 사용하여 --exclude-from. 예를 들어

rsync ... --exclude-from=<([ "${#excludes[@]}" -gt 0 ] && printf -- '- %s\n' "${excludes[@]}") ... 

답변2

--exclude={'*.jpg', '*.mp4'}하지 않는다버팀대 확장여는 중괄호와 닫는 중괄호가 별도의 단어로 되어 있기 때문입니다. 중괄호 확장은 변수 부분이 있는 단일 단어에서 여러 단어를 만듭니다. 공간을 제거하세요.

rsync … --exclude={'*.jpg','*.mp4'} …

또는

rsync … --exclude='*.'{jpg,mp4} …

쉘 확장의 결과는 두 단어 와 이어야 하므로 after =가 필요합니다 . 가 없으면 확장은 , 및 3개의 단어가 됩니다 .--exclude--exclude=*.jpg--exclude=*.mp4=--exclude*.jpg*.mp4

관련 정보