बैश में एक उपयोगिता कार्यक्रम के लिए जंजीर कॉल को परिमित करें


12

मेरे पास एक ब्लैक बॉक्स UNIX प्रोग्राम है जिसका उपयोग बैश शेल में किया जाता है जो स्टड से डेटा के कॉलम को पढ़ता है, उन्हें प्रोसेस करता है (एक स्मूदिंग इफ़ेक्ट लागू करता है) फिर स्टैडआउट को आउटपुट करता है। मैं इसे यूनिक्स पाइप द्वारा उपयोग करता हूं, जैसे

generate | smooth | plot  

अधिक चौरसाई के लिए, मैं चिकना दोहरा सकता हूं, इसलिए इसे बैश कमांड लाइन से मंगाया जाएगा

generate | smooth | smooth | plot   

या और भी

generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot

इससे अनहोनी हो रही है। मैं एक बॅश रैपर बनाना चाहता हूं ताकि वह smoothअपने आउटपुट को सही तरह से पाइप कर सके और smoothकई बार मनमाने ढंग से एक नए उदाहरण में वापस आ सके।

generate | newsmooth 5 | plot

के बजाय

generate | smooth | smooth | smooth | smooth | smooth | plot

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

smoothकार्यक्रम के लिए कोई तर्क नहीं हैं ।

क्या इस तरह के एक कार्यक्रम को "रैप" करने के लिए एक और अधिक सुंदर तरीका कॉल की संख्या को मानकीकृत करना है?


1
मुझे उम्मीद है कि आपका उदाहरण प्रश्न के लिए एक मजबूर मामला है और वास्तविक आवश्यकता नहीं है
एरियलएमएनज

जवाबों:


18

आप इसे एक पुनरावर्ती कार्य में लपेट सकते हैं:

smooth() {
  if [[ $1 -gt 1 ]]; then # add another call to function
    command smooth | smooth $(($1 - 1)) 
  else
    command smooth # no further 
  fi
}

आप इस का उपयोग करेंगे

generate | smooth 5 | plot

जो के बराबर होगा

generate | smooth | smooth | smooth | smooth | smooth | plot

यह सही है, बिल्कुल आवश्यकतानुसार व्यवहार करता है। और अब मुझे bash "कमांड" कीवर्ड के बारे में पता चला।
डायने विल्बर


5

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

टी एल; डॉ

आपके नमूना मामले के लिए पूरी कमांड-लाइन होगी:

generate | eval 'smooth |'{,,,,} plot

ध्यान दें:

  • यदि आप अधिक या कम पुनरावृत्ति चाहते हैं तो अल्पविराम जोड़ें या निकालें smooth |
  • ब्रेस एक्सपेंशन द्वारा निर्मित अंतिम स्ट्रिंग में शामिल |होने के plotकारण पहले कोई नहीं हैsmooth |
  • आप smoothतब तक तर्क भी प्रदान कर सकते हैं , जब तक कि आप उन्हें खुले ब्रेस से पहले उद्धृत भाग के भीतर सही ढंग से शामिल कर सकते हैं; किसी भी स्थिति में याद रखें कि आप उन्हें कमांड की सभी पुनरावृत्ति प्रदान करेंगे

यह काम किस प्रकार करता है

कोमा से अलग ब्रेस एक्सपेंशन आपको गतिशील रूप से तारों का उत्पादन करने की अनुमति देता है, जिनमें से प्रत्येक एक निर्दिष्ट निश्चित भाग और निर्दिष्ट चर भागों से बना होता है। यह उतने ही तारों का उत्पादन करता है, जितने चर भागों को दर्शाते हैं, जैसे a{b,c,d}उत्पादन करते हैं ab ac ad

यहाँ थोड़ा टोटका यह है कि यदि आप ब्रेड के अंदर केवल कॉमा के साथ खाली चर भागों की सूची बनाते हैं , तो ब्रेस विस्तार केवल निश्चित भाग की प्रतियाँ ही पैदा करेगा। उदाहरण के लिए:

smooth{,,,,}

उत्पादन करेंगे:

smooth smooth smooth smooth smooth

ध्यान दें कि 4 कॉमा 5 smoothस्ट्रिंग्स का उत्पादन करते हैं। बस यही है कि यह ब्रेस एक्सपेंशन कैसे काम करता है: यह स्ट्रिंग्स को कई कॉमा प्लस प्लस बनाता है।

निश्चित रूप से आपके मामले में आपको |प्रत्येक को अलग करने की भी आवश्यकता है smooth, इसलिए बस इसे निश्चित भाग में जोड़ें लेकिन ध्यान रखें कि इसे ठीक से उद्धृत करने के लिए शेल को एक बार में व्याख्या न करें । अर्थात्:

'smooth|'{,,,,}

उत्पादन करेंगे:

'smooth|' 'smooth|' 'smooth|' 'smooth|' 'smooth|'

हमेशा तय हिस्सा रखने का ख्याल रखना तुरंत खुला ब्रेस के निकट के बीच कोई रिक्त स्थान यानी ' और {

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

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

इस प्रकार, यह सब करने के लिए, आपके नमूना मामले के लिए पूरी कमांड-लाइन होगी:

generate | eval 'smooth |'{,,,,} plot

1
यदि यह उन स्थानों पर उपयोग किया जाता है, जहां कॉल को मानकीकृत किया जाता है, तो महत्वपूर्ण सुरक्षा चिंताएं हैं। पुनरावर्ती बाश समारोह बनाम पुनरावृत्ति "eval" स्ट्रिंग बिल्डिंग पर मेरा जवाब देखें : कौन सा बेहतर प्रदर्शन करता है? स्टैक ओवरफ्लो पर।
चार्ल्स डफी

1
@CharlesDuffy मैं पूरी तरह से इस बात पर सहमत हूं कि evalजब कोई व्यक्ति अविश्वासित, गैर-स्वच्छता प्रदान करता है, तो इसका मूल्यांकन करने के लिए उपयोग किए जाने पर निहित जोखिमों के बारे में , इसका मूल्यांकन करने के लिए चर के साथ प्रयोग किया जाता है, जो मामले से जुड़े "अज्ञात" सामग्री को ले जा सकता है। दूसरी ओर, evalकमांड के त्वरित "प्लंबिंग" के लिए भी बहुत काम किया जा सकता है, खासकर जब प्रॉम्प्ट पर उपयोग किया जाता है, जैसे हाथ पर मामला लगता है, जहां evalउपयोगकर्ता द्वारा मैन्युअल रूप से टाइप किया गया एक शाब्दिक स्ट्रिंग केवल इनपुट होगा। व्यक्ति
LL3

जैसा कि पहले से ही कहीं और देखा गया है, आप हमेशा eval strकुछ दिखावा और मूर्खता के साथ बदल सकते हैं . /dev/stdin <<<str। न केवल यह मूर्खों पर एक छाप बना देगा, यह आपकी पीठ से @CharlesDuffy भी रखेगा ;-)
pizdelect

1
@pizdelect, आप LL3 की पूर्व टिप्पणी को ध्यान से पढ़ सकते हैं - यह संतुलित, अति सूक्ष्म और बुद्धिमान है। (वास्तव में, मेरी अपनी प्रारंभिक टिप्पणी में ऐसी बारीकियाँ थीं जिन्हें आप नज़रअंदाज़ करते दिखते हैं; "यदि उन मामलों में उपयोग किया जाता है जहां कॉल को मानकीकृत किया जाता है" एक महत्वपूर्ण अंतर है: LL3 का उदाहरण पैरामीटर नहीं है, जिससे यह सुरक्षित हो जाता है)।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.