मैंने एक स्क्रिप्ट लिखी, जो उद्धरण के साथ मेरे लिए उन तर्कों को उत्पन्न कर सकती है
यदि शेल के लिए आउटपुट ठीक से उद्धृत किया गया है, और आप आउटपुट पर भरोसा करते हैं , तो आप इस eval
पर चल सकते हैं ।
मान लें कि आपके पास एक शेल है जो सरणियों का समर्थन करता है, तो आपके द्वारा प्राप्त तर्कों को संग्रहीत करने के लिए एक का उपयोग करना सबसे अच्छा होगा।
यदि ./gen_args.sh
उत्पादन जैसा होता है 'foo bar' '*' asdf
, तो हम परिणामों के साथ eval "args=( $(./gen_args.sh) )"
एक सरणी को पॉप्युलेट करने के लिए चला सकते हैं args
। यही कारण है कि तीन तत्वों होगा foo bar
, *
, asdf
।
हम "${args[@]}"
सरणी तत्वों को व्यक्तिगत रूप से विस्तारित करने के लिए हमेशा की तरह उपयोग कर सकते हैं :
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(उद्धरण नोट करें। "${array[@]}"
सभी तत्वों को अलग-अलग तर्कों के रूप में अनमॉडिफाइड किया गया है । उद्धरणों के बिना सरणी तत्व शब्द विभाजन के अधीन हैं। उदाहरण के लिए बशगाइड पर ऐरे पेज देखें ।)
हालाँकि , eval
किसी भी शेल प्रतिस्थापन को खुशी से चलाएगा, इसलिए $HOME
आउटपुट में आपके होम डायरेक्टरी का विस्तार होगा, और कमांड प्रतिस्थापन वास्तव में शेल चलाने में एक कमांड चलाएगा eval
। का एक आउटपुट "$(date >&2)"
एक एकल खाली ऐरे तत्व बनाता है और स्टडआउट पर वर्तमान तिथि प्रिंट करता है। यह एक चिंता का विषय है अगर gen_args.sh
कुछ अविश्वसनीय स्रोत से डेटा मिलता है, जैसे नेटवर्क पर एक अन्य होस्ट, अन्य उपयोगकर्ताओं द्वारा बनाए गए फ़ाइल नाम। आउटपुट में मनमाना आदेश शामिल हो सकते हैं। (यदि get_args.sh
स्वयं दुर्भावनापूर्ण था, तो उसे कुछ भी आउटपुट करने की आवश्यकता नहीं होगी, यह सीधे दुर्भावनापूर्ण आदेशों को चला सकता है।)
शेल क्विंग का एक विकल्प, जो कि बिना परल के पार्स करना कठिन है, आपकी स्क्रिप्ट के आउटपुट में विभाजक के रूप में कुछ अन्य चरित्र का उपयोग करना होगा। आपको वास्तविक दलीलों में किसी एक को चुनने की आवश्यकता नहीं होगी।
चलो चुनते हैं #
, और स्क्रिप्ट आउटपुट है foo bar#*#asdf
। अब हम कमांड के आउटपुट को तर्कों में विभाजित करने के लिए अनक्लोडेटेड कमांड एक्सटेंशन का उपयोग कर सकते हैं ।
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
आपको IFS
बाद में वापस सेट करने की आवश्यकता होगी यदि आप स्क्रिप्ट में कहीं और शब्द विभाजन पर निर्भर करते हैं ( unset IFS
इसे डिफ़ॉल्ट बनाने के लिए काम करना चाहिए), और set +f
यदि आप बाद में ग्लोबिंग का उपयोग करना चाहते हैं तो भी इसका उपयोग करें।
यदि आप बैश या किसी अन्य शेल का उपयोग नहीं कर रहे हैं जिसमें सरणियाँ हैं, तो आप उसके लिए स्थितीय मापदंडों का उपयोग कर सकते हैं। बदलें args=( $(...) )
के साथ set -- $(./gen_args.sh)
और प्रयोग "$@"
के बजाय "${args[@]}"
तो। (यहां भी, आपको उद्धरण चिह्नों की आवश्यकता है "$@"
, अन्यथा स्थितीय पैरामीटर शब्द विभाजन के अधीन हैं।)
eval
इसका उपयोग किया जा सकता है, लेकिन यह आमतौर पर अनुशंसित नहीं है।xargs
के रूप में अच्छी तरह से विचार करने के लिए कुछ है