rashync एक बैश स्क्रिप्ट में `लापता ट्रेलिंग-” `के बारे में शिकायत कर रहा है


13

स्क्रीन सेशन में एक सर्वर से दूसरे सर्वर पर rsync फ़ाइलों की कोशिश कर रहा है। हर बार लंबी कमांड लिखने के बजाय, मैंने बैश स्क्रिप्ट में डालने का फैसला किया। हालाँकि, जब मैं इसे चलाता हूं, मुझे एक 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ऊपर बताए गए कमांड की तरह कुछ का उपयोग करें (ध्यान दें कि यह कमांड के बाद एक आवारा जगह को प्रिंट करता है, लेकिन यह आमतौर पर नहीं होता है ' t मामला)।

यहाँ सरणी + 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} (मुझे पता है, यह काफी पुराना है, लेकिन अभी भी एक है "मिसिंग ट्रेलिंग-" इन द रिमोट-शेल कमांड "की खोज करते समय पहले लिंक)
फ्रांसेस्को मार्केटी-स्टैसी

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"

मैंने अपने सिस्टम पर आपकी स्क्रिप्ट का थोड़ा सरलीकृत संस्करण आज़माया और आपको वही त्रुटि संदेश मिला; इस समाधान ने इसे ठीक कर दिया।


1

Ssh कॉन्फ़िगरेशन फ़ाइल का उपयोग करना भी एक वैध विकल्प है। यहाँ आप अपनी ~/.ssh/configफ़ाइल में क्या डाल / जोड़ सकते हैं:

Port 10022
Cipher des

आप इन मापदंडों को इन पंक्तियों के साथ जोड़कर Host xyz.domain.whateverऔर उन्हें इंडेंट करके दूरस्थ होस्ट द्वारा फ़िल्टर कर सकते हैं:

Host 192.168.1.15
    Port 10022
    Cipher des
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.