पाइप का उपयोग करके बैश कार्यों की रचना कैसे करें?


18

इस फैशन में मेरे कुछ कार्य परिभाषित हैं:

function f {
  read and process $1
  ...
  echo $result
}

मैं उन्हें एक साथ रचना करना चाहता हूं ताकि आह्वान ऐसा लगे f | g | h

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


या तो आप कुछ चाहते हैं h(g(f(...)))या प्रत्येक फ़ंक्शन मानक इनपुट ( read x; ...) से पढ़ता है और मानक आउटपुट ( echo ...) को लिखता है ।
वॉनब्रांड

जवाबों:


21

एक संभावित दृष्टिकोण while...readआपके कार्यों के अंदर एक निर्माण करना होगा जो एसटीडीआईएन के माध्यम से फ़ंक्शन में आए किसी भी डेटा को संसाधित करेगा, उस पर काम करेगा, और फिर परिणामी डेटा को एसटीडीयूएसटी के माध्यम से वापस बाहर कर देगा।

function X {
  while read data; do
    ...process...
  done
}

देखभाल के साथ खर्च करने की आवश्यकता होगी कि आप अपने while ..read..घटकों को कैसे कॉन्फ़िगर करते हैं क्योंकि वे डेटा के प्रकार पर अत्यधिक निर्भर होंगे जो वे मज़बूती से उपभोग करने में सक्षम होंगे। एक इष्टतम कॉन्फ़िगरेशन हो सकता है जो आप के साथ आ सकते हैं।

उदाहरण

$ logF() { while read data; do echo "[F:$(date +"%D %T")] $data"; done; }
$ logG() { while read data; do echo "G:$data";                    done; }
$ logH() { while read data; do echo "H:$data";                    done; }

यहां प्रत्येक कार्य अपने आप होता है।

$ echo "hi" | logF
[F:02/07/14 20:01:11] hi

$ echo "hi" | logG
G:hi

$ echo "hi" | logH
H:hi

यहां वे हैं जब हम उन्हें एक साथ उपयोग करते हैं।

$ echo "hi" | logF | logG | logH
H:G:[F:02/07/14 19:58:18] hi

$ echo -e "hi\nbye" | logF | logG | logH
H:G:[F:02/07/14 19:58:22] hi
H:G:[F:02/07/14 19:58:22] bye

वे विभिन्न शैलियों के इनपुट ले सकते हैं।

#-- ex. #1
$ cat <<<"some string of nonsense" | logF | logG | logH
H:G:[F:02/07/14 20:03:47] some string of nonsense

#-- ex. #2    
$ (logF | logG | logH) <<<"Here comes another string."
H:G:[F:02/07/14 20:04:46] Here comes another string.

#-- ex. #3
$ (logF | logG | logH)
Look I can even
H:G:[F:02/07/14 20:05:19] Look I can even
type to it
H:G:[F:02/07/14 20:05:23] type to it
live
H:G:[F:02/07/14 20:05:25] live
via STDIN
H:G:[F:02/07/14 20:05:29] via STDIN
..type Ctrl + D to stop..

#-- ex. #4
$ seq 5 | logF | logG | logH
H:G:[F:02/07/14 20:07:40] 1
H:G:[F:02/07/14 20:07:40] 2
H:G:[F:02/07/14 20:07:40] 3
H:G:[F:02/07/14 20:07:40] 4
H:G:[F:02/07/14 20:07:40] 5

#-- ex. #5
$ (logF | logG | logH) < <(seq 2)
H:G:[F:02/07/14 20:15:17] 1
H:G:[F:02/07/14 20:15:17] 2

4

स्लम के उत्तर के लिए एक परिशिष्ट के रूप में , मैंने कुछ अलग-अलग नलियों के साथ प्रयोग किया, जो फ़ंक्शन तर्क के रूप में थे:

$ sayTuple() { 
    IFS= read -r -d $'\0' d1
    IFS= read -r -d $'\0' d2
    echo "sayTuple: -$d1- -$d2-"
}

नोट: sayTupleदो बार -d $'\0'किसी भी स्थान के आसपास के इनपुट से निपटने के लिए एक शून्य-समाप्त रिकॉर्ड पढ़ता है IFS=echoचारों ओर से पीछे के रिकॉर्ड-

परिणाम दिखाता है कि यह सही ढंग से शून्य-समाप्त इनपुट युक्त है \nऔर \t:

$ printf "%s\0%s\0" "Hello " $' Brave\n\tWorld' | sayTuple 
sayTuple: -Hello - - Brave
        World-

कृपया टिप्पणियों में सुधार के लिए सुझाव जोड़ें, यह एक दिलचस्प विषय है।


अपने विचार की तरह +1। हम इसके बजाय एक लूप डाल सकते हैं जो इसे मनमाने ढंग से # args लेने की अनुमति देगा। sayTuple() { arr=() ; while IFS= read -r -d $'\0' arg; do arr+="$arg"; done; echo "sayTuple: ${arr[@]}"; }
SLM

लगता है कि आपको ऐसा करने में सक्षम होना चाहिए, IFS= read -r -d $'\0' -a argलेकिन मुझे यह काम करने के लिए नहीं मिला। यह हटाने की अनुमति देगा while, जो अनावश्यक लगता है, लेकिन केवल एक ही पैटर्न था जो मुझे काम करने के लिए मिल सकता था।
स्लम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.