चुनना आपको है। यदि आप $@
इसके किसी भी मूल्य को उद्धृत नहीं करते हैं तो अतिरिक्त विस्तार और व्याख्या से गुजरना पड़ता है। यदि आप इसे उद्धृत करते हैं, तो सभी तर्कों को पारित कर दिया जाता है, तो फ़ंक्शन को इसके विस्तार शब्दशः में पुन: प्रस्तुत किया जाता है। आप कभी भी शेल सिंटैक्स टोकन को मज़बूती से संभाल नहीं पाएंगे, जैसे &>|
और जैसे भी हो, वैसे भी अपने आप को तर्कों को पार्स किए बिना - और इसलिए आप अपने फ़ंक्शन को किसी एक को सौंपने के अधिक उचित विकल्पों के साथ छोड़ दिए जाते हैं:
- वास्तव में एक ही सरल कमांड के निष्पादन में उपयोग किए जाने वाले शब्द
"$@"
।
... या ...
- आपके तर्कों का एक और विस्तृत और व्याख्या किया गया संस्करण, जो तब केवल एक साधारण कमांड के रूप में एक साथ लागू किया जाता है
$@
।
न तो रास्ता गलत है अगर यह जानबूझकर है और यदि आप जो चुनते हैं उसका प्रभाव अच्छी तरह से समझा जाता है। दोनों तरीकों से एक के बाद एक फायदे हैं, हालांकि दूसरे के फायदे शायद ही कभी उपयोगी होते हैं। फिर भी...
(run_this(){ $@; }; IFS=@ run_this 'ls@-dl@/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
... यह बेकार नहीं है , बस शायद ही कभी अधिक उपयोग की संभावना है । और एक bash
शेल में, क्योंकि bash
डिफ़ॉल्ट रूप से अपने वातावरण के लिए एक वैरिएबल परिभाषा को छड़ी नहीं करता है , यहां तक कि तब भी जब परिभाषा एक विशेष बिलिन की कमांड-लाइन या एक फ़ंक्शन के लिए प्रस्तुत की जाती है, के लिए वैश्विक मान $IFS
अप्रभावित है, और इसकी घोषणा स्थानीय है केवल run_this()
कॉल करने के लिए ।
इसी तरह:
(run_this(){ $@; }; set -f; run_this ls -l \*)
ls: cannot access *: No such file or directory
... ग्लोबिंग भी विन्यास योग्य है। उद्धरण एक उद्देश्य की सेवा करते हैं - वे कुछ भी नहीं के लिए हैं। उनके बिना शेल विस्तार अतिरिक्त व्याख्या से गुजरता है - कॉन्फ़िगर करने योग्य व्याख्या। यह हुआ करता था - कुछ बहुत पुराने गोले के साथ - जो विश्व स्तर पर सभी इनपुट पर लागू किया $IFS
गया था , और न केवल विस्तार। वास्तव में, कहा जाता है कि गोले बहुत व्यवहार करते हैं जैसे उन्होंने मूल्य के सभी इनपुट शब्दों को तोड़ दिया । और इसलिए, यदि आप जो खोज रहे हैं, वह बहुत पुराना शेल व्यवहार है, तो आपको उपयोग करना चाहिए ।run_this()
$IFS
run_this()
मैं इसकी तलाश नहीं कर रहा हूं, और मैं इस समय इसके लिए एक उपयोगी उदाहरण के साथ आने के लिए काफी सख्त हूं। मैं आम तौर पर उन कमांडों के लिए पसंद करता हूं जो मेरे शेल को चलाता है जो मैं इसे टाइप करता हूं। और इसलिए, पसंद को देखते हुए, मैं लगभग हमेशा होता run_that()
। सिवाय इसके कि...
(run_that(){ "$@"; }; IFS=l run_that 'ls' '-ld' '/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
बस के बारे में कुछ भी उद्धृत किया जा सकता है। कमांडो उद्धृत किया जाएगा। यह काम करता है क्योंकि जब तक कमांड वास्तव में चलाया जाता है, तब तक सभी इनपुट शब्द पहले ही उद्धरण हटाने से गुजर चुके हैं - जो शेल की इनपुट व्याख्या प्रक्रिया का अंतिम चरण है। इसलिए शेल के बीच की व्याख्या के बीच केवल 'ls'
और ls
केवल अंतर हो सकता है - और इसीलिए उद्धरण ls
यह सुनिश्चित करता है कि नामित किसी अन्य उपनामls
को मेरे उद्धृत ls
कमांड शब्द के लिए प्रतिस्थापित नहीं किया गया है। इसके अलावा, केवल वही चीजें जो उद्धरण को प्रभावित करती हैं वे हैं शब्दों का परिसीमन (जो कि कैसे और क्यों चर / इनपुट-व्हाट्सएप उद्धरण काम करता है) , और मेटाचैटर्स और आरक्षित शब्दों की व्याख्या।
इसलिए:
'for' f in ...
do :
done
bash: for: command not found
bash: do: unexpected token 'do'
bash: do: unexpected token 'done'
आप कभी भी run_this()
या तो ऐसा नहीं कर पाएंगे run_that()
।
लेकिन फ़ंक्शन के नाम, या $PATH
'डी कमांड्स, या बिलिन ठीक उद्धृत या निर्विवाद रूप से निष्पादित होंगे, और यह वास्तव में कैसे run_this()
और run_that()
पहली जगह में काम करते हैं। आप $<>|&(){}
उनमें से किसी के साथ भी उपयोगी कुछ नहीं कर पाएंगे । छोटा है eval
, है।
(run_that(){ "$@"; }; run_that eval printf '"%s\n"' '"$@"')
eval
printf
"%s\n"
"$@"
लेकिन इसके बिना, आपके द्वारा उपयोग किए जाने वाले उद्धरणों के आधार पर आप एक साधारण कमांड की सीमा के लिए विवश हैं (यहां तक कि जब आप नहीं करते क्योंकि $@
प्रक्रिया की शुरुआत में एक उद्धरण की तरह काम करता है जब कमांड मेटाचैटर्स के लिए पार्स किया जाता है) । एक ही बाधा कमांड-लाइन असाइनमेंट और पुनर्निर्देशन का सच है, जो फ़ंक्शन के कमांड-लाइन तक सीमित हैं। लेकिन यह कोई बड़ी बात नहीं है:
(run_that(){ "$@";}; echo hey | run_that cat)
hey
मुझे आसानी से <
पुनर्निर्देशित इनपुट या >
आउटपुट मिल सकता है क्योंकि मैंने पाइप खोला था।
वैसे भी, गोल-गोल तरीके से, यहाँ कोई सही या गलत तरीका नहीं है - प्रत्येक तरीके के उपयोग हैं। यह सिर्फ इतना है कि आपको इसे लिखना चाहिए क्योंकि आप इसे इस्तेमाल करने का इरादा रखते हैं, और आपको पता होना चाहिए कि आपका क्या मतलब है। उद्धरण उद्धृत करने का एक उद्देश्य हो सकता है - अन्यथा उद्धरण बिल्कुल नहीं होगा - लेकिन यदि आप उन्हें अपने उद्देश्य से प्रासंगिक कारणों के लिए छोड़ देते हैं, तो आप सिर्फ बुरा कोड लिख रहे हैं। तुम्हारा मतलब क्या है; मैं वैसे भी कोशिश करता हूं।
run_that
व्यवहार निश्चित रूप से है कि मैं क्या उम्मीद करूँगा (क्या होगा अगर कमांड के पथ में एक स्थान है?)। यदि आप अन्य व्यवहार चाहते हैं, तो निश्चित रूप से आप इसे कॉल- साइट पर अनक्वोट कर देंगे जहां आपको पता है कि डेटा क्या है? मुझे इस फ़ंक्शन को कॉल करने की उम्मीद हैrun_that ls -l
, जो दोनों संस्करणों में समान है। क्या कोई ऐसा मामला है जिससे आपको अलग तरह की उम्मीद है?