Bash 스크립트에서`missing trailing-'`에 대해 불평하는 rsync


13

화면 세션에서 한 서버에서 다른 서버로 파일을 재 동기화하려고합니다. 매번 긴 명령을 작성하는 대신 Bash 스크립트를 작성하기로 결정했습니다. 그러나 실행할 때 Missing trailing-" in remote-shell command.오류가 발생합니다.

스크립트에서 무엇이 잘못되었는지 궁금합니다.

root@127.0.0.1:~# /raid/data/module/bin/rbk.sh Movies /raid/data/Movies rsync_target/

/raid/data/module/bin/screen -S Movies 

/opt/bin/rsync --rsh="ssh -p 10022 -c des"\
--rsync-path="/opt/bin/rsync" --inplace --progress -a -vv \
/raid/data/Movies sys@192.168.1.15:/raid/data/rsync_target/

Missing trailing-" in remote-shell command.
rsync error: syntax or usage error (code 1) at main.c(361) [sender=3.0.5]

스크립트는 먼저 수행 할 작업을 반영한 다음 명령을 실행합니다. 아래는 내 스크립트 덤프입니다.

#!/bin/bash
SCREEN="/raid/data/module/bin/screen"
SCREENOPT="-S"
SCREEN_TITLE=$1

RSYNC="/opt/bin/rsync"
RSYNCOPT="--rsh=\"ssh -p 10022 -c des\" --rsync-path=\"/opt/bin/rsync\" --inplace --progress -a -vv"

SOURCE=$2

REMOTE_USER="sys@"
REMOTE_HOST="192.168.1.15"
REMOTE_BASE=":/raid/data/"
REMOTE_TARGET=$3

echo ${SCREEN} ${SCREENOPT} ${SCREEN_TITLE}

echo ${RSYNC} ${RSYNCOPT} ${SOURCE} ${REMOTE_USER}${REMOTE_HOST}${REMOTE_BASE}${REMOTE_TARGET}
${RSYNC} ${RSYNCOPT} ${SOURCE} ${REMOTE_USER}${REMOTE_HOST}${REMOTE_BASE}${REMOTE_TARGET}

답변:


23

짧은 대답 : BashFAQ # 050을 참조하십시오 .

긴 대답 : 당신이 겪고있는 문제는 변수에 따옴표를 포함시키는 것이 생각하는 방식으로 작동하지 않는다는 것입니다. 특히 변수가 교체되기 전에 따옴표가 구문 분석되므로 변수의 값에 따옴표가 포함되어 있으면 제대로 작동하기에 너무 늦습니다. 명령 행에서 설정 RSYNCOPT="--rsh=\"ssh -p 10022 -c des\" ..."한 다음 사용 ${RSYNCOPT}하면 변수의 따옴표가 구문 분석되지 않고 그냥 일반 문자로 취급됩니다. 따라서, rsync에 명령이 하나의 파라미터를 수신하는 것이 아니라 --rsh=ssh -p 10022 -c des, 그 수신 5 : --rsh="ssh, -p, 10022, -c, 및 des". --rsh 명령에 작은 (일치하지 않는) 따옴표가 포함되어 있으므로 오류가 발생합니다.

더 나은 상황을 보려면 set -x을 사용하여 셸이 각 명령을 실행하기 전에 각 명령을 인쇄하도록하거나 (실제로 발생하는 것을 볼 수 있음) echo ${whatever}(를 잘못 오도하는)으로 바꾸십시오 printf "%q " ${whatever}; echo.

이를 해결하는 몇 가지 방법이 있습니다. 하나는 RSYNCOPT변수에 변수 를 저장하지 않는 것입니다. 다른 하나는 RSYNCOPT간단한 문자열 대신 배열 로 저장 하는 것입니다 (이 혼란없이 단어 경계를 추적 할 수 있음).

명령을 실행하기 전에 인쇄하려면 set -xrsync 명령 이전을 사용 하고 끄고 + x를 설정하거나 printf위에 나열된 명령 과 같은 명령을 사용하십시오 ( 명령 뒤에 표유 공간을 인쇄하지만 일반적으로 ' 상관 없음).

다음은 array + printf 접근 방식입니다.

...
RSYNCOPT=(--rsh="ssh -p 10022 -c des" --rsync-path=\"/opt/bin/rsync\" --inplace --progress -a -vv)
...
printf "%q " ${SCREEN} ${SCREENOPT} ${SCREEN_TITLE}
echo

printf "%q " ${RSYNC} "${RSYNCOPT[@]}" ${SOURCE} ${REMOTE_USER}${REMOTE_HOST}${REMOTE_BASE}${REMOTE_TARGET}
echo
${RSYNC} "${RSYNCOPT[@]}" ${SOURCE} ${REMOTE_USER}${REMOTE_HOST}${REMOTE_BASE}${REMOTE_TARGET}

어쨌든, 올바른 방향으로 당신이 기능을 더 읽을 수 있는지 나를 설득하여 제공된 (또는 올바른 형식의 경우 적어도 그렇게된다) 링크에 얼핏 나를 가리키는 주셔서 감사합니다 : run_rsync() { /opt/bin/rsync "--rsh=\"ssh -p 10022 -c des\" --rsync-path=\"/opt/bin/rsync\" --inplace --progress -a -vv" $1 $2 } run_rsync ${SOURCE} ${REMOTE_USER}${REMOTE_HOST}${REMOTE_BASE}${REMOTE_TARGET} (나는이 꽤 오래 알고,하지만 여전히 하나 "원격 셸 명령에서 누락 된 추적"을 검색 할 때 첫 번째 링크 중 하나)
Francesco Marchetti-Stasi

6

당신의 탈출과 이스케이프 처리되지 않은 인용 부호의 미로 $RSYNCOPT는 나를 도용하는 것을 혼란스럽게합니다. rsync 및 / 또는 ssh 및 / 또는 로컬 또는 원격 쉘을 혼동한다는 사실은 놀랍지 않습니다.

백 슬래시를 추가하거나 제거하여이 작업을 수행하는 방법이있을 수 있지만 대신 다음 해결 방법을 제안합니다.

바꾸다:

RSYNCOPT="--rsh=\"ssh -p 10022 -c des\" --rsync-path=\"/opt/bin/rsync\" --inplace --progress -a -vv"

으로:

export RSYNC_RSH="ssh -p 10022 -c des"
RSYNCOPT="--rsync-path=\"/opt/bin/rsync\" --inplace --progress -a -vv"

시스템에서 약간 단순화 된 스크립트 버전을 시도했지만 동일한 오류 메시지가 나타납니다. 이 해결 방법으로 해결했습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.