स्ट्रिंग में बैश कमांड निष्पादित कर रहा है जब मैं स्ट्रिंग बनाता हूं, तब नहीं जब मैं इसे बाद में उपयोग करता हूं


10

मैं शेल स्क्रिप्टिंग के लिए अपेक्षाकृत नया हूं, लेकिन लगभग एक स्क्रिप्ट पूरी कर चुका हूं, जो लैफ्टप प्रोग्राम का उपयोग करता है । जिस स्क्रिप्ट से मुझे परेशानी हो रही है, वह तब है जब मैं कमांड्स की एक लंबी स्ट्रिंग (अलग करके ;) बनाता हूं ।

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

मैं जो देख रहा हूँ वह यह है कि tailप्रोग्राम - बैकटिक्स में लिपटे हुए - को तब चलाया जा रहा है जब लूप के लिए पुनरावृति हो रही है, लेकिन तब नहीं जब मैं अपनी स्क्रिप्ट में बाद में कमांड के स्ट्रिंग को लागू करता हूं।

दुर्भाग्य से, $ somefile की सामग्री इस चरण में निरीक्षण के लिए तैयार नहीं है। जब मुझे इसकी आवश्यकता होती है, तो मैं इसे कैसे निष्पादित कर सकता हूं, और स्ट्रिंग बनाते समय नहीं?

जवाबों:


8

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

सबसे आसान तरीका यह है कि $()इस $तरह से बचते हुए वाक्यविन्यास का उपयोग करें कि चर परिभाषा परिभाषा $()के समय संलग्न कमांड को निष्पादित नहीं करती है । चेतावनी यह है कि अंतिम परिणाम को फिर से मूल्यांकन किया जाना चाहिए (के माध्यम से eval) शेल द्वारा वास्तविक निष्पादन के समय नेस्टेड कमांड को निष्पादित करने के लिए।

एक उदाहरण को देखना बहुत आसान है, इसलिए इसे एक लें, जिसे आपको सही रास्ते पर रखना चाहिए:

for((i=0;i<10;i++)); do 
  date +%s.%N  # Print a timestamp (in format seconds.nanoseconds)
  test="echo \$(date +%s.%N)" # Save a command to do the same
  sleep 1      # Sleep for a second
  eval "$test" # Evaluate the command saved in variable 'test'
  echo         # Print a new line before the next iteration
done

ऊपर दिए गए उदाहरण से नमूना उत्पादन (एक पुनरावृत्ति के लिए छंटनी):

1398832186.133661344
1398832187.139076728

आप देखेंगे कि प्रत्येक लूप के लिए दूसरा टाइमस्टैम्प पहले के बाद एक दूसरे के बारे में है। इसके विपरीत, यदि आप भागने के बिना एक ही परीक्षण करने $में testपरिभाषा और हटाने eval, दो timestamps लगभग भरपाई कर देंगे।

evalज्यादातर स्थितियों में उपयोग करने की आदत न डालें , लेकिन यह उनमें से एक है जहाँ मुझे इससे बचने का एक अच्छा तरीका नहीं पता है। उम्मीद है कि यह मदद करता है। सौभाग्य!


बहुत बहुत धन्यवाद, मैंने कोशिश की है $(...)कि जैसा कि Hauke ​​ने सुझाव दिया है, लेकिन बैकलैश कुंजी है।
रिकी

खुशी है कि यह मदद की - याद रखें, हालांकि, यहां कुंजी वास्तव में है evalक्योंकि आप एक ही काम कर सकते हैं $और अपने आदेश को घेरने के लिए 'डबल कोट्स ( ") के बजाय सिंगल कोट्स ( ) का उपयोग करके बच नहीं सकते हैं ।
daBeamer

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

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

1
@ रेकी मुझे @HukeLaging के सभी बिंदुओं से सहमत होना होगा। कोड के रूप में माइनस echoकाम नहीं करने वाला है क्योंकि इसमें कोई कमांड नहीं है eval, बल्कि एक स्ट्रिंग है। यदि आपके पास हमारे लिए अधिक प्रासंगिक उदाहरण है, तो हम मदद करने का प्रयास कर सकते हैं।
daBeamer

6

उद्धृत करने के कई स्तर हैं। दोहरे उद्धरण चिह्नों ( "...") की रक्षा श्वेत रिक्ति और कई विशेष वर्ण ( ~, &, |, ;, ...) लेकिन पैरामीटर विस्तार और आदेश प्रतिस्थापन नहीं रोकता है।

आपको '"खतरनाक" पात्रों के सामने एकल उद्धरण ( ) या बैकस्लैश की आवश्यकता है।

सामान्य तौर पर: आपको $(tail ...)बैकटिक्स के बजाय उपयोग करने पर विचार करना चाहिए । बैकटिक्स पुराने मानक हैं लेकिन हम इतने पुराने के बारे में बात कर रहे हैं जिससे $()अधिकांश लोगों के लिए समस्या पैदा नहीं होती है। नया संस्करण पढ़ना आसान है और इसे नेस्ट किया जा सकता है। अकेले sx पर यहाँ समस्याओं को स्वरूपित करते हैं ...


तेजी से उत्तर के लिए धन्यवाद Hauke। दुर्भाग्य से अनुशंसित के साथ बैकटिक्स को प्रतिस्थापित करना $(...)अभी भी एक ही परिणाम पैदा करता है - शेल तब निष्पादित होता है जब मेरी स्ट्रिंग परिभाषित होती है।
रिकी

@ रेकी वह वैकल्पिक सुझाव नहीं थे। आप का उपयोग करेंगे, $()लेकिन आप वैसे भी एकल उद्धरण की जरूरत है।
हॉके लैजिंग

तो उन पात्रों का कोई भी संयोजन हासिल नहीं करेगा जो मैं बाद में हूं?
रिकी

@ रेकी "आपको या तो एकल उद्धरणों की आवश्यकता है" के बारे में समझने में क्या मुश्किल है? आप स्पष्ट रूप से यह भी एक कोशिश नहीं देते।
हॉके लैगिंग

वास्तव में मैंने किया था, लेकिन जब मैं एकल उद्धरण का उपयोग करता हूं तो गूंज उस रेखा पर एक सामान्य स्ट्रिंग के रूप में सब कुछ प्रिंट कर देगी। एक उदाहरण प्रदान करना शायद कितना कठिन है?
रिकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.