संक्षिप्त उत्तर: BashAQ # 50 देखें : मैं एक चर में एक कमांड डालने की कोशिश कर रहा हूं, लेकिन जटिल मामले हमेशा विफल होते हैं! ।
लंबा उत्तर: यह उस आदेश के कारण है जिसमें bash कमांड लाइन को पार्स करता है। विशेष रूप से, यह चर मानों का विस्तार करने से पहले पाइप और पुनर्निर्देश जैसी चीजों की तलाश करता है, और विस्तारित मूल्यों में पाइप आदि के लिए वापस नहीं जाता है और फिर से देखता है। अनिवार्य रूप से, चर को पार्सिंग प्रक्रिया के माध्यम से लगभग आधे रास्ते में प्रतिस्थापित किया जाता है, इसलिए मूल्य केवल निष्पादित होने से पहले आधे रास्ते से पार्स हो जाता है।
इसे हल करने के लिए, आपको @ slhck के प्रश्न का उत्तर देने की आवश्यकता है: पहली जगह में एक चर में कमांड क्यों संग्रहीत है? वास्तविक समस्या क्या है जिसे आप हल करने का प्रयास कर रहे हैं? वास्तविक लक्ष्य के आधार पर, कई संभावित समाधान हैं:
इसे एक चर में संग्रहीत न करें, बस इसे सीधे निष्पादित करें। बाद में उपयोग के लिए आदेशों को संग्रहीत करना मुश्किल है, और यदि आपको वास्तव में ज़रूरत नहीं है, तो बस नहीं।
एक चर के बजाय एक फ़ंक्शन का उपयोग करें। यही कारण है कि वे सब के बाद:
i() { cat -nT index.php |grep 'someregex'; }
i
इसका मुख्य नुकसान यह है कि आप फ़ंक्शन को गतिशील रूप से नहीं बना सकते - आप सशर्त रूप से फ़ंक्शन से कोड को शामिल या बाहर नहीं कर सकते हैं (हालांकि फ़ंक्शन में सशर्त तत्व हो सकते हैं जो निष्पादित होने पर चुने जाते हैं)।
का उपयोग करें eval
। इसे एक अंतिम उपाय माना जाना चाहिए, क्योंकि अप्रत्याशित व्यवहार प्राप्त करना आसान है। यह अनिवार्य रूप से एक और पूर्ण पार्सिंग पास के माध्यम से कमांड चलाता है, इसलिए सभी पाइप आदि को उनका पूरा अर्थ मिलता है - लेकिन इसका मतलब यह भी है कि आपके द्वारा सोचा गया कमांड के कुछ हिस्सों को सिर्फ पार्स किया गया है और शायद निष्पादित किया गया है। शेल मेटाचैकर्स (पाइप, अर्धविराम, उद्धरण / एपोस्ट्रोफ, आदि) वाले फाइलनाम में अजीब और कभी-कभी खतरनाक प्रभाव हो सकते हैं। यदि आप उपयोग करते हैं eval
, तो कम से कम स्ट्रिंग को डबल-कोट करें, अन्यथा इसकी सामग्री अनिवार्य रूप से एक-आध बार पार्स हो जाती है, यहां तक कि अजीब परिणाम भी।
i="cat -nT index.php |grep 'someregex'"
eval "$i"
EDIT: एक और मानक स्टोर-ए-कमांड-इन-इन-चर दृष्टिकोण एक साधारण चर के बजाय एक सरणी का उपयोग करना है। यह आपको परेशानी के बिना जटिल तर्कों (जैसे रिक्त स्थान वाले) के साथ एक कमांड स्टोर करने की अनुमति देता है, लेकिन पाइप और रीडायरेक्ट जैसी चीजों को स्टोर नहीं करेगा। तो, सरणी दृष्टिकोण इस विशेष मामले में उपयोगी नहीं होगा।