내 스크립트에는 다음이 있습니다.
sshkey="/Users/me/some path/with spaces/id_rsa"
dstport=...
dstparent=...
dstuserhost=...
rsync -az --delete -e "ssh -i $sshkey -p $dstport" $src $dstuserhost:$dstparent
내가 그것을 실행하면 나는 얻는다 :
rsync: "/Users/me/some"에 대한 link_stat 실패: 해당 파일 또는 디렉터리 없음 (2)
답변1
주위에 작은따옴표를 추가하면 $sshkey
문제가 해결됩니다.
rsync -az --delete -e "ssh -i '$sshkey' -p '$dstport'" "$src" "$dstuserhost:$dstparent"
값 $sshkey
은 큰따옴표로 묶인 문자열 내에 있기 때문에 호출 전에 대화형 셸에 의해 확장되지만 작은따옴표는 rsync
연결을 설정하기 위해 호출이 이루어질 때 문자열이 더 이상 분할되는 것을 방지합니다.rsync
ssh
$sshkey
자체에는 작은따옴표 문자가 포함되어 있지 않다고 가정합니다 .
답변2
"내부" 따옴표를 삽입해야 합니다. 내가 말할 것
printf -v rsh_cmd 'ssh -i "%s" -d "%s"' "$sshkey" "$dstport"
...
rsync ... -e "$rsh_cmd"
답변3
-e
이 옵션에 대한 인수는 rsync
쉘 명령줄이 아니라 rsync
명령줄입니다. rsync
Bourne 쉘과 다른 자체 규칙을 사용하여 구문 분석됩니다.
모든 쉘과 마찬가지로 공백 문자를 매개변수 구분 기호로 처리하고 Bourne 쉘과 마찬가지로 작은따옴표와 큰따옴표(백슬래시 제외)를 인용 연산자로 처리합니다. 셸 확장(예 $var
: $(cmd)
, , *.txt
, ~user
...) 은 수행하지 않습니다 .
따라서 해당 의사 명령줄에 임의의 인수를 포함하려면 큰따옴표 문자 자체(작은따옴표로 묶임)를 제외하고 인수를 큰따옴표로 묶거나 작은따옴표로 묶을 수 있습니다. 작은따옴표 문자 자체의 경우(큰따옴표로 묶임)
예를 들어 SSH 키 파일이 이면 /cygdrive/c/John Doe/.ssh/John "Dude" Doe's.rsa
매개변수 는 또는 -e
와 유사해야 합니다 .'/cygdrive/c/John Doe/.ssh/John "Dude" Doe'"'"'s.rsa'
"/cygdrive/c/John Doe/.ssh/John "'"'"Dude"'"'" Doe's.rsa"
이를 수행하기 위해 전용 함수를 정의할 수 있습니다.재동기화 참조좋다:
# ksh93/bash/zsh syntax:
rsync_quote() {
local arg="$1"
arg=${arg//\'/\'\"\'\"\'}
printf "'%s'\n" "$var"
}
rsync -e "ssh -i $(rsync_quote "$sshkey") -p $dstport" ...
또 다른 옵션은 쉘을 인수로 전달한 다음 명령줄을 -e
해석하는 것입니다 . ssh
이것의 한 가지 장점은 쉘이 변수 확장을 할 수 있다는 것입니다.
KEY=$sshkey PORT=$dstport SSH_COMMAND='ssh -i "$KEY" -p "$PORT" "$@"' \
rsync -e "sh -c 'eval \"\$SSH_COMMAND\"' sh" ...
: 으로 실행하면 strace -fe execve -s 999
다음과 같이 확장되는 것을 볼 수 있습니다.
execve("/usr/bin/rsync", ["rsync", "-e", "sh -c 'eval \"$SSH_COMMAND\"' sh", "1/", "localhost:2/"], 0x7ffc03b83678 /* 74 vars */) = 0
strace: Process 7208 attached
[pid 7208] execve("/bin/sh", ["sh", "-c", "eval \"$SSH_COMMAND\"", "sh", "localhost", "rsync", "--server", "-e.LsfxC", ".", "2/"], 0x7ffcc6ad0f28 /* 74 vars */) = 0
[pid 7209] execve("/usr/bin/ssh", ["ssh", "-i", "/cygdrive/c/John Doe/.ssh/John \"Dude\" Doe's.rsa", "-p", "2222", "localhost", "rsync", "--server", "-e.LsfxC", ".", "2/"], 0x5651a0c144a8 /* 74 vars */) = 0