2012-02-28 11 views
10

मैं एक स्ट्रिंग वैरिएबल को प्रतिस्थापित करने की कोशिश कर रहा हूं, जिसमें एकाधिक उद्धृत शब्द हैं, जो कमांड के पैरामीटर के रूप में हैं।उद्धृत, बहु-शब्द तारों को तर्क के रूप में कैसे बदला जाए?

इस प्रकार

, निम्न उदाहरण स्क्रिप्ट (नोट मामला है, जिसकी वजह उत्पादन stderr करने के लिए लॉग इन करने की में -x) को देखते हुए

#!/bin/bash -x 

myArg="\"hello\" \"world\"" 
echo "string is:" $myArg 

exit 

कौन सा हमें देता है,

+ myArg='"hello" "world"' 
+ echo 'string is:' '"hello"' '"world"' 
string is: "hello" "world" 
+ exit 


रेखा दो दिखाता है कि वास्तव में आदेश को क्या पारित किया जाता है; बैश ने स्ट्रिंग में प्रत्येक शब्द को एकल उद्धरण जोड़ा है। यदि मैं इसके बजाय, "$ myArg" उद्धृत करता हूं, वही होता है लेकिन प्रत्येक शब्द के बजाय पूरी स्ट्रिंग के लिए होता है।

अब, कल्पना करें कि echo के बजाय, हम एक प्रोग्राम को स्ट्रिंग पास कर रहे हैं जहां कुछ तर्कों को "*" (जिसे खोल द्वारा विस्तारित नहीं किया जाना चाहिए) को उद्धृत करने की आवश्यकता है।

स्पष्टीकरण के लिए, मैं नहीं चाहता कि विस्तार के दौरान एकल उद्धरण जोड़े गए हों। मैं इसे कैसे प्राप्त कर सकता हूं?

+0

आप क्या कर रहे हैं?जब तक आप 'eval' के साथ कुछ नहीं कर रहे हैं, चाहे कार्यक्रम में पारित स्ट्रिंग में '" * "' या '*' कोई फर्क नहीं पड़ता है। – Sorpigal

+0

किसी भी व्यक्ति को भ्रमित करने के लिए: शेबैंग में '-x' नोट करें, जिससे आउटपुट लॉग हो जाता है। – user123444555621

+0

@ Pumbaa80, वास्तव में, मैंने प्रश्न के स्पष्टीकरण को जोड़ा है। –

उत्तर

13

उद्धरण का उपयोग न करें, एक सरणी का उपयोग करें (BashFAQ #050 देखें):

$ myArgs=("hello" "world" "multiword arg with * ?") 
+ myArgs=("hello" "world" "multiword arg with * ?") 
$ echo "${myArgs[@]}" 
+ echo hello world 'multiword arg with * ?' 
hello world multiword arg with * ? 

यदि इसे वास्तव में एक स्ट्रिंग के भीतर उद्धृत तारों के रूप में होना आवश्यक है, तो आपको या तो eval "echo $myArg" जैसे कुछ उपयोग करना होगा (यदि आप सावधान नहीं हैं तो कुछ वास्तव में गंदे बग का कारण बन सकते हैं) या इसे स्वयं पार्स करें (जो मुश्किल होने जा रहा है)।

+0

यह Arrays दृष्टिकोण पूरी तरह से काम करता है, बहुत बहुत धन्यवाद! पीएस। सबहेल से किसी भी प्रिंट सेशन को मूल खोल द्वारा व्याख्या किया जाता है, इसलिए ऐसा कोई भी 'eval' कथन देना गलत परिणाम देता है। –

4

आप एक पैरामीटर के रूप में एक चर मूल्य पारित करने के लिए (अतः पर मामलों की 99%) चाहते हैं, बस उचित quoting का उपयोग करें:

arg="foo bar" 
command "$arg" 

आप कई तर्क, उपयोग सरणियों पास करना चाहते हैं:

args=("foo bar" "baz ban" bay) 
command "${args[@]}" 
+0

जैसा कि द्वारा स्पष्ट किया गया है @ गॉर्डन-डेविसन, Arrays वास्तव में जवाब थे, बहुत धन्यवाद! –

0

मुझे नहीं लगता कि यह ऐसा कर रहा है जो आपको लगता है कि यह कर रहा है।

[~]$ myArg="\"hello\" \"world\"" 
[~]$ echo "string is:" $myArg 
string is: "hello" "world" 

मैं किसी भी kind- echo के बिना किसी अतिरिक्त उद्धरण तीन तर्क तार हो जाता है देखते हैं।

[~]$ cargs(){ echo $#; } 
[~]$ cargs "string is:" $myArg 
3 

बैश पहले चर का विस्तार होगा, इसलिए

cargs "string is:" $myArg 

हो जाता है (हालांकि शाब्दिक बिना backslashes- क्यों स्ट्रिंग भागने एक PITA है यह है)

cargs "string is:" "\"hello\"" "\"world\"" 

और आर्ग सरणी है:

0x00:string is:0 
0x0B:"hello"0 
0x13:"world"0 
0x1B:0 

अब, यदि आप *, या उनमें से किसी एक में ग्लोब पथ विस्तार जोड़ते हैं, तो इस बिंदु पर बैश इसे विस्तारित करेगा, जब तक कि आप इसे से बचें, या अपने शाब्दिक कमांड में सिंगल कोट्स का उपयोग न करें।

[~]$ cargs "string is:" $myArg * 
19 
[~]$ cargs "string is:" $myArg "\*" 
4 
[~]$ cargs "string is:" $myArg '*' 
4 
+0

इको का * आउटपुट * उद्धृत शब्दों को पूरी तरह प्रिंट करता है, वास्तव में, लेकिन इनपुट तर्क इको को पारित करते हैं (जैसा कि प्रश्न में डीबग आउटपुट की पंक्ति दो पर दिखाया गया है) एकल उद्धृत-डबल उद्धृत ('"str"') है, जो दुर्भाग्य से मैं जिस उपकरण का उपयोग कर रहा हूं उसके लिए अर्थहीन इनपुट है। –

संबंधित मुद्दे