rsync는 스크립트에 옵션을 전달하지 않으면 현재 디렉터리를 복사합니다.

rsync는 스크립트에 옵션을 전달하지 않으면 현재 디렉터리를 복사합니다.

다음은 한 디렉터리에서 다른 디렉터리로 파일을 복사하는 Ubuntu 18.04의 스크립트입니다. 현재 디렉터리()의 파일이 /media/rmerriam/Backup/rsync_backup대상에 복사된다는 점을 제외하면 모든 것이 잘 작동합니다. 소스 경로에 전혀 없었으므로 전혀 복사해서는 안 됩니다.

수동 실행(유무와 상관없음 -s):

rmerriam@mysticlakelinux:/media/rmerriam/test/rsync_backup$ rsync -auv -s ../src/ ../dest
sending incremental file list

sent 59 bytes  received 12 bytes  142.00 bytes/sec
total size is 0  speedup is 0.00
rmerriam@mysticlakelinux:/media/rmerriam/test/rsync_backup$ ls ../dest

실행된 스크립트에는 다음이 없습니다 -s.

===========================
./merge.sh
 
 ../src/
 ../dest
rsync -auv  ../src/ ../dest
sending incremental file list
./    <====== added why???
merge.sh
merge_all.sh
merge_backups.sh

sent 3,124 bytes  received 76 bytes  6,400.00 bytes/sec
total size is 2,835  speedup is 0.89
rmerriam@mysticlakelinux:/media/rmerriam/test/rsync_backup$ ls ../dest
merge_all.sh  merge_backups.sh  merge.sh

옵션을 사용하여 스크립트를 실행합니다 -s.

rmerriam@mysticlakelinux:/media/rmerriam/test/rsync_backup$ ./merge.sh ../src/ ../dest -s
===========================
./merge.sh
 -s
 ../src/
 ../dest
rsync -auv -s ../src/ ../dest
sending incremental file list
./

sent 66 bytes  received 19 bytes  170.00 bytes/sec
total size is 0  speedup is 0.00
rmerriam@mysticlakelinux:/media/rmerriam/test/rsync_backup$ ls ../dest

결과:수동 실행 및 옵션으로 파일이 -s이동되지 않았습니다 . 스크립트 $PWD가 없으면 -s파일이 복사됩니다.

스크립트는 -s./디렉터리를 소스 디렉터리로 추가하지 않습니다. 왜?

명령줄은 다음 echo과 같이 표시되며 동일합니다. 스크립트에 다른 동작이 있는 이유는 무엇입니까?

스크립트는 다음과 같습니다.

#!/bin/bash

# base script for copying files to the common directory.
# only copies newer files

printf '===========================\n'
printf "$0\n $3\n $1\n $2\n"

echo rsync -auv "$3"    "$1" "$2"
rsync -auv "$3"    "$1" "$2"

참고로:rsync version 3.1.2 protocol version 31

답변1

스크립트에 버그가 있습니다. 틀림없이 rsync에도 버그가 있습니다. 왜냐하면 이상한 데이터를 전달하면 조용히 놀라운 일을 하고, 그냥 잘못되도록 두는 것이 더 낫기 때문입니다. 그러나 어느 쪽이든 스크립트가 작동하지 않습니다.

문제가 있는 줄은 다음과 같습니다.

rsync -auv "$3"    "$1" "$2"

이는 script( ) "$3"의 세 번째 인수가 a로 시작하는 경우 -rsync에 대한 옵션입니다 . 그러나 세 번째 인수가 a로 시작하지 않는 경우 -(스크립트에 인수가 두 개(또는 그 이하)만 있는 경우 포함)는 옵션이 아닌 인수입니다. Rsync는 여러 소스 디렉터리를 허용하므로 "$3"a로 시작하지 않으면 복사 를 -요청하는 것 입니다 ."$3""$1""$2"

./merge.sh ../src/ ../dest

../src/rsync 에게 빈 문자열을 ../dest.

대부분의 응용 프로그램은 파일 이름을 찾을 때 빈 문자열을 거부합니다. 그러나 빈 문자열이 파일 이름으로 허용될 때마다 이는 현재 디렉터리를 나타냅니다. 이는 상대 경로가 절대 경로로 변환되는 방식과 일치합니다. 경로가 상대 경로인 경우( 로 시작하지 않음 /) 현재 작업 디렉터리의 절대 경로 앞에 슬래시를 추가하면 동등한 절대 경로를 얻게 됩니다. 이것을 빈 문자열(슬래시로 시작하지 않기 때문에 상대 경로임)에 적용하면 끝에 슬래시가 있는 현재 작업 디렉터리, 즉 현재 작업 디렉터리를 얻게 됩니다.

Rsync는 빈 문자열을 현재 디렉터리로 허용합니다. 그래서 당신이 말한 것과 정확히 일치합니다.

빈 문자열을 매개변수로 전달하는 것은 의도적인 것보다 버그일 가능성이 더 높습니다. 현재 디렉토리를 지정하는 가장 짧고 널리 사용되는 방법은 .(점)입니다. 따라서 rsync는 매개변수가 유효하지 않아 오류가 발생했다는 오류 메시지를 인쇄해야 한다고 말할 수 있습니다.

스크립트에서 선택적인 추가 옵션을 허용하기를 원하지만 이를 구현하는 방식에 따르면 해당 추가 옵션은 필수입니다. 선택사항으로 만들려면 스크립트에 세 번째 매개변수가 있는지 확인하세요.

if [ $# -lt 2 ]; then
  echo >&2 "$0: too few arguments (SRC and DEST are required)"
  exit 120
elif [ $# -eq 2 ]; then
  rsync -auv "$1" "$2"
elif [ $# -eq 3 ]; then
  rsync -auv "$3" "$1" "$2"
else
  echo >&2 "$0: too many arguments (only one OPTIONS argument is permitted)"
  exit 120
fi

하지만 인터페이스는 이상합니다. 왜 최대 하나의 옵션만 허용합니까? 다양한 옵션을 수락할 수도 있습니다(왜 통과할 수 없나요 -q --dry-run?). 이는 사용자가 이해하기 쉽고 구현하기도 더 쉽습니다. 게다가 관례는 옵션을 전달하는 것입니다.앞으로옵션이 아닌 인수, 이후가 아닙니다. 인터페이스가 단순화되어 다양한 옵션을 수용할 수 있게 되면 코드를 단순화하여 다음과 같이 할 수 있습니다.

rsync -auv "$@"

답변2

가서 문제를 확인 rsync하고 알아보세요"빈 따옴표는 SRC 디렉토리에 cwd를 추가합니다.". $3추가 옵션을 추가하는 스크립트에 문제가 있습니다 . 보통은 비어 있어서 그게 범인이죠. Added는 -s매개변수를 null이 아닌 것으로 만들어 이 문제를 방지합니다.

이 수동 실행을 통해 문제가 확인되었습니다.

rsync ""  -auv ../src/ ../dest
sending incremental file list
created directory ../dest
./
merge.sh
merge_all.sh
merge_backups.sh

sent 3,124 bytes  received 106 bytes  6,460.00 bytes/sec
total size is 2,835  speedup is 0.88

관련 정보