बैश स्ट्रिंग संघनन पैरामीटर सूची बनाने के लिए उपयोग किया जाता है


12

बैश के इस टुकड़े को देखते हुए:

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}

इको अपेक्षा के अनुसार PARMS स्ट्रिंग दिखाता है, कोई त्रुटि प्रदर्शित नहीं होती है, लेकिन rsync चुपचाप कार्य करता है जैसे कि + = द्वारा जोड़े गए विकल्प मौजूद नहीं थे। हालाँकि, यह उम्मीद के मुताबिक काम करता है:

PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}

मुझे लगता है कि मैंने बैश कोट्स के साथ कुछ खराब कर दिया है (हमेशा उन लोगों के साथ समस्या थी), लेकिन यह बिल्कुल सुनिश्चित नहीं है कि स्ट्रिंग को सही तरीके से बनाया गया है, भले ही विकल्प की अनदेखी क्यों और क्यों की गई हो।


1
echo "$PARMS"और rsync "${PARMS}"...
— जसोवरीयन

यह bashबिना किसी बदलाव के संस्करण 4.2.25 के साथ मेरे लिए काम करता है ।
— एंथन

जवाबों:


17

इस बीच एक अंतर है:

PARMS+="... --exclude='.git'"

तथा

... --exclude='.git'

पहले में, एकल उद्धरण स्वयं उद्धरण के अंदर होते हैं, इसलिए वे वस्तुतःrsync तर्कों के रूप में दिए गए प्रतिस्थापित पाठ में मौजूद होते हैं । rsyncएक तर्क मिलता है जिसका मूल्य है --exclude='.git'। दूसरे में, एकल उद्धरणों की व्याख्या शेल द्वारा उस समय की जाती है जब वे लिखे जाते हैं, क्योंकि वे स्वयं उद्धरणों के अंदर नहीं होते हैं, और rsyncदेखने के लिए मिलते हैं --exclude=.git।

इस मामले में, आपको एक ही उद्धरण की आवश्यकता नहीं है - .gitअपने आप में एक पूरी तरह से मान्य शेल शब्द है, जिसमें कोई विशेष वर्ण नहीं है, इसलिए आप इसे कमांड में शाब्दिक रूप से उपयोग कर सकते हैं।

इस तरह की चीज़ के लिए बेहतर है, हालांकि, एक सरणी है :

PARMS=(-rvu)
PARMS+=(--delete --exclude='.git')
rsync "${PARMS[@]}"

यह आपके आदेश को अलग-अलग शब्दों के रूप में बनाता है, जिस भी उद्धरण के साथ आप व्याख्या करना चाहते हैं उस समय आप सरणी लाइन लिखते हैं। सरणी में प्रत्येक प्रविष्टि के लिए एक अलग तर्क के रूप में "${PARMS[@]}"फैलता है, भले ही तर्क में विशेष वर्ण या रिक्त स्थान हों, इसलिए rsyncदेखता है कि आपने जो लिखा था जैसा आप चाहते थे।


bash${PARMS}विस्तार के बाद शब्द विभाजन का प्रदर्शन किया। इसलिए एकल उद्धरण की व्याख्या शेल द्वारा भी की गई थी।
— cuonglm

2
कोशिश करो! मैंने किया। उद्धरण बने रहते हैं, और अगर बीच में रिक्त स्थान थे, तो वे वैसे भी विभाजित बिंदु हैं।
— माइकल होमर

@Gnouc: बैश आदमी पेज से: "उद्धरण हटाने: पूर्ववर्ती विस्तार के बाद, पात्रों के सभी गैर उद्धृत घटनाओं \ , 'और "। कि ऊपर विस्तार निकाल दिए जाते हैं में से एक से परिणाम नहीं" "उपरोक्त विस्तार" में पैरामीटर विस्तार शामिल है जो विस्तार करता है ${PARMS}।
— camh

धन्यवाद। तो मैं समझता हूं कि उस मामले में दोहरे के अंदर एकल उद्धरण को छोड़ने से काम चल जाएगा, लेकिन पूर्णता के लिए - अगर मुझे कुछ विशेष पात्रों को उद्धृत करने की आवश्यकता है और अपने बाद के दृष्टिकोण का उपयोग नहीं करना चाहते हैं तो क्या होगा?
— neuviemeporte

यदि आपके विशेष वर्ण IFS(आम तौर पर, व्हाट्सएप) का हिस्सा नहीं हैं , तो आपको उन्हें उद्धृत करने की आवश्यकता नहीं है। यदि वे हैं, तो आप भाग्य से बाहर हैं जब तक कि आप एक साथ कुछ हैक नहीं करते हैं eval- यह सामान्य रूप से एक मिसफिट है, और इससे निपटने के लिए एरे सही तरीका है।
— माइकल होमर

2

@ मिचेल होमर के जवाब के अलावा , आप bash eval फ़ंक्शन का उपयोग कर सकते हैं :

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo "$PARMS"
eval "rsync ${PARMS} . "'"${TARGET}"'

2
आप कर सकते हैं, लेकिन आपको नहीं करना चाहिए। इसके उपयोग से बचने के लिए विशेष रूप से एरेज़ को जोड़ा गया था eval।
— 21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.