एकल उद्धरण के अंदर चर का उपयोग कैसे करें


11

मेरे पास एक एप्लिकेशन है जो सिंगल कोट्स में एम्बेडेड डबल कोट्स में इनपुट विशेषताओं के रूप में लेता है। उदाहरण के लिए इस सही कमांड को लें:

command -p 'cluster="cl1"'

इसे स्वचालित करने के लिए, मैंने $CLUSTERएक चर के रूप में उपयोग करके एक बैश फ़ाइल बनाई । मेरी आज्ञा कैसी होनी चाहिए? दूसरे शब्दों में, मुझे cl1 के बजाय क्या रखना चाहिए?

कृपया ध्यान दें, यदि मैंने उपरोक्त आदेश को संशोधित किया है, तो इसे स्वीकार नहीं किया जाएगा। उदाहरण के लिए: command -p "cluster=cl1"स्वीकार नहीं किया जाता है


2
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
मिकसेर

एक और संभावना (यदि आप वैरिएबल के cliअंदर उद्धरण के बिना स्टोर करना पसंद करते हैं CLUSTER):CLUSTER='cl1'; command -p 'cluster="'"$CLUSTER"'"'
jimmij

अंत में, मुझे सही उत्तर मिला। धन्यवाद @ जिमीज
मोहम्मद-जाफर NEHME

जवाबों:


8

ऐसा लगता है कि आपकी कमांड संभवतः कमांड-लाइन पर दिए गए तर्कों के आधार पर पर्यावरण चर निर्धारित कर रही है। यह आप कर सकते हैं:

CLUSTER=cl1; cluster=$CLUSTER command

... और आह्वान पर इसके लिए अपना वातावरण निर्धारित किया।

अन्यथा, शेल उद्धरण आमतौर पर तर्क वितर्क करते हैं या शेल व्याख्या से अन्य विशेष शेल वर्णों से बच जाते हैं। आप विभिन्न नियमों के आधार पर अन्य प्रकारों के भीतर विभिन्न प्रकार के शेल-कोट्स (और इसलिए बच सकते हैं ) :

  • "''''" - एक सॉफ्ट-कोटेड स्ट्रिंग में किसी भी संख्या में हार्ड-कोट्स हो सकते हैं।
  • "\""- एक \बैकस्लैश "एक "नरम-उद्धृत स्ट्रिंग के भीतर एक नरम- उद्धरण से बच सकता है ।
    • इस संदर्भ में एक \\बैकस्लैश भी खुद से बच जाता है, \$विस्तार टोकन, और \nनीचे बताए अनुसार ईवलाइन, लेकिन अन्यथा शाब्दिक रूप से व्यवहार किया जाता है।
  • "${expand} and then some"- एक नरम-उद्धृत स्ट्रिंग में एक व्याख्या किए गए शेल $विस्तार हो सकते हैं ।
  • '"\'- 'हार्ड-कोटेड स्ट्रिंग में हार्ड-कोट के अलावा कोई भी चरित्र हो सकता है '
  • \- एक अयोग्य बैकस्लैश शाब्दिक व्याख्या के लिए किसी भी निम्नलिखित चरित्र से बच जाएगा - यहां तक ​​कि एक अन्य बैकस्लैश - एक \nईवालाइन को छोड़कर ।
    • एक \\newline केस में, \बैकस्लैश और ewline दोनों \nको पूरी तरह से परिणामी व्याख्या की गई कमांड से हटा दिया जाता है।
  • ${parameter+expand "$parameter"}- शेल विस्तार से उत्पन्न उद्धरण कुछ विशेष मामलों को छोड़कर लगभग कभी भी सीमांकक मार्कर के रूप में काम नहीं करते हैं। मैं यहाँ इनका वर्णन करने का उपक्रम नहीं करूँगा।

मैं इसे अजीब मानता हूं कि कोई भी एप्लिकेशन अपने कमांड-लाइन आर्ग में उद्धरण की व्याख्या करेगा। इस तरह का अभ्यास बहुत मायने नहीं रखता है - गोले के लिए, कम से कम - एक उद्धरण का प्राथमिक उद्देश्य आम तौर पर एक तर्क को परिसीमित करना है। आह्वान पर, हालांकि, तर्कों को हमेशा पहले ही\0NUL पात्रों के साथ सीमांकित किया जाता है और इसलिए एक उद्धरण बहुत उद्देश्य से काम नहीं कर सकता है।

यहां तक ​​कि एक शेल आम तौर पर केवल एक आह्वान तर्क में उद्धरण की व्याख्या करने के लिए परेशान करेगा जब इसे एक -cस्विच के साथ कहा जाता है - जो यह दर्शाता है कि इसका पहला ऑपरेंड वास्तव में एक शेल स्क्रिप्ट है जिसे इसे आह्वान पर चलना चाहिए। यह दो बार मूल्यांकन किए गए इनपुट का मामला है ।

सभी ने कहा, आप कमांड-लाइन पर तर्कों के माध्यम से शाब्दिक उद्धरण पारित करने के लिए कई चीजें कर सकते हैं। उदाहरण के लिए:

CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"

जैसा कि मैंने पहले एक टिप्पणी में उल्लेख किया है, आप "एक विस्तार के भीतर उद्धरणों को समाहित कर सकते हैं जो स्वयं "उद्धृत है।

CLUSTER=cl1; command -p "cluster=\"$CLUSTER\""

आप उद्धृत स्ट्रिंग के भीतर "एक \बैकस्लैश के साथ बच सकते हैं "

CLUSTER=cl1; command -p cluster='"'"$CLUSTER"'"'

आप अपने इच्छित अंतिम परिणाम के लिए @jimmij नोट के रूप में आने के लिए शैलियों को वैकल्पिक और संक्षिप्त कर सकते हैं

CLUSTER=cl1; ( set -f; IFS=; command -p cluster=\"$CLUSTER\" )

आप फ़ाइल नाम पीढ़ी और $IFSविभाजन दोनों को अक्षम कर सकते हैं - जिससे $expansionसभी को उद्धृत करने की आवश्यकता से बचा जा सकता है - और इसलिए केवल उद्धरण उद्धृत करें। यह शायद ओवरकिल है।

अंत में, एक और प्रकार का शेल-उद्धरण है जिसका उपयोग किया जा सकता है। जैसा कि मैंने उल्लेख किया है कि sh -c "$scriptlet"शेल मंगलाचरण के रूप में अक्सर कमांड-लाइन पर शेल की स्क्रिप्ट प्रदान करने के लिए उपयोग किया जाता है। जब $scriptletइस तरह के जब उद्धरण अन्य उद्धरण शामिल होना चाहिए के रूप में - - हालांकि जटिल हो जाता है यह अक्सर एक यहाँ-दस्तावेज़ और प्रयोग करने में फायदेमंद हो सकता है sh -sजहां खोल विशेष रूप से सभी निम्नलिखित आवंटित करने के लिए निर्देश दिया जाता है - के बजाय ऑपरेंड के रूप में यह एक में करना होगा स्थितीय मापदंडों के -cमामले और फिर भी इसकी स्क्रिप्ट को लेना है stdin

यदि आपके कमांड को इस तरह से उद्धरणों की व्याख्या करनी चाहिए तो मैं इसे बेहतर समझूंगा यदि यह एक फ़ाइल इनपुट में ऐसा कर सकता है। उदाहरण के लिए:

CLUSTER=cl1
command --stdin <<-SCRIPT
    cluster="$CLUSTER"
SCRIPT

यदि आप <<here-documentतत्कालीन सीमांकक को उद्धृत नहीं करते हैं, तो इसकी सभी सामग्रियों का लगभग वैसा ही व्यवहार किया जाता है, जैसा कि वे "नरम-उद्धृत किया गया था - सिवाय इसके कि "दोहरे उद्धरणों का स्वयं विशेष रूप से व्यवहार नहीं किया जाता है। और इसलिए अगर हम इसके catबजाय ऊपर चलाते हैं :

CLUSTER=cl1
cat <<-SCRIPT
        cluster="$CLUSTER"
SCRIPT

... यह प्रिंट करता है ...

cluster="cl1"

1

जैसे mikeserv ने लिखा है:

 CLUSTER='"cl1"'; command -p "cluster=$CLUSTER" 

"दोहरे उद्धरण" हर शाब्दिक कि रिक्त स्थान / अक्षरों से परे और शामिल हर विस्तार: "$var", "$(command "$var")", "${array[@]}", "a & b"। का प्रयोग करें 'single quotes'कोड या शाब्दिक के लिए $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'
Http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments http://wiki.bash-hackers.org/syntax/words देखें


आप सही हैं, धन्यवाद। लेकिन, स्वचालन के बारे में क्या? मान लीजिए कि मैं ग्राहक पढ़ना चाहता हूं? मैं एक ही समस्या के साथ फिर से फंस
जाऊंगा

@ उमि - स्वचालन कोई बड़ी बात नहीं है, हालांकि आपको "वर्णों के चर को पवित्र करना होगा - केवल पहला और अंतिम पर्याप्त होना चाहिए। यहाँ वास्तविक समस्या एक आर्ग में उद्धरण की व्याख्या करने वाला आपका ऐप है। एक तर्क में एक उद्धरण की व्याख्या करना लगभग एक अच्छा विचार नहीं है क्योंकि एक उद्धरण केवल एक तर्क को परिसीमित करने का एक साधन होना चाहिए - और आह्वान पर कि \0NULहर मामले में परिसीमन को संभाला जाए । संभवतः एप्लिकेशन को आपके द्वारा वांछित जानकारी को पास करने का एक बेहतर तरीका है? एक command --'script=/path/to/some/file'या कुछ और की तरह?
1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.