पाइप उत्पादन और बैश में निकास स्थिति पर कब्जा


420

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

इसलिए मैं यह करता हूं:

command | tee out.txt
ST=$?

समस्या यह है कि चर ST teeकमांड के नहीं और बाहर निकलने की स्थिति को पकड़ता है । इसे कैसे हल किया जा सकता है?

ध्यान दें कि कमांड लंबे समय से चल रहा है और आउटपुट को फ़ाइल में रीडायरेक्ट करने के लिए इसे बाद में देखने के लिए मेरे लिए अच्छा समाधान नहीं है।


1
[["$ {PIPESTATUS [@]}" = ~ [^ 0 \]]] && इको-ई "मैच - त्रुटि मिली" || इको-ई "नो मैच - ऑल गुड" यह एक ही बार में एरे के सभी मूल्यों का परीक्षण करेगा और यदि कोई पाइप वैल्यू लौटाता है तो कोई त्रुटि संदेश नहीं देगा। यह पाइप की स्थिति में त्रुटियों का पता लगाने के लिए एक बहुत मजबूत सामान्यीकृत समाधान है।
ब्रायन एस। विल्सन

जवाबों:


519

एक आंतरिक बैश चर कहा जाता है $PIPESTATUS; यह एक ऐसा सरणी है जो आपके कमांड के अंतिम अग्रभूमि पाइप लाइन में प्रत्येक कमांड की निकास स्थिति रखता है।

<command> | tee out.txt ; test ${PIPESTATUS[0]} -eq 0

या एक अन्य विकल्प जो अन्य गोले (जैसे zsh) के साथ भी काम करता है, वह पाइपफेल को सक्षम करेगा:

set -o pipefail
...

पहला विकल्प थोड़ा अलग वाक्यविन्यास के कारण काम नहीं करता है zsh


21
यहाँ PIPESTATUS AND Pipefail के उदाहरणों के साथ एक अच्छी व्याख्या है: unix.stackexchange.com/a/73180/7453
स्लम

18
नोट: $ PIPESTATUS [0] पाइप में पहले कमांड की निकास स्थिति रखता है, $ PIPESTATUS [1] दूसरी कमांड की निकास स्थिति, और इसी तरह।
सरल

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

4
निर्विवाद चर विस्तार के बारे में चिंतित लोगों के लिए: बाहर निकलने की स्थिति हमेशा बैश में 8-बिट पूर्णांक से रहित होती है, इसलिए इसे उद्धृत करने की कोई आवश्यकता नहीं है। यह आम तौर पर यूनिक्स के तहत भी है, जहां निकास स्थिति को स्पष्ट रूप से 8-बिट के रूप में परिभाषित किया गया है , और इसे अपने तार्किक निषेध को परिभाषित करते हुए POSIX द्वारा भी अहस्ताक्षरित माना जाता है ।
पलेक

3
आप भी इस्तेमाल कर सकते हैं exit ${PIPESTATUS[0]}
चारण

142

बैश का उपयोग set -o pipefailसहायक है

पाइपफेल: एक गैर-शून्य स्थिति के साथ बाहर निकलने के लिए एक पाइप लाइन का वापसी मूल्य एक गैर-शून्य स्थिति या शून्य के साथ बाहर निकलने के लिए अंतिम आदेश की स्थिति है।


23
यदि आप पूरी स्क्रिप्ट की पाइफ़ेल सेटिंग को संशोधित नहीं करना चाहते हैं, तो आप केवल स्थानीय रूप से विकल्प सेट कर सकते हैं:( set -o pipefail; command | tee out.txt ); ST=$?
Jaan

7
@ जान यह एक उपधारा चलाएगा। यदि आप उससे बचना चाहते हैं, तो आप कर सकते हैं set -o pipefailऔर फिर कमांड कर सकते हैं , और तुरंत बाद set +o pipefailविकल्प को अनसेट करने के लिए।
लाइनस अरवर

2
नोट: प्रश्न पोस्टर पाइप का "सामान्य निकास कोड" नहीं चाहता है, वह 'कमांड' का रिटर्न कोड चाहता है। साथ -o pipefailवह करता है, तो पाइप में विफल रहता है पता होगा, लेकिन अगर दोनों 'कमांड' और 'टी' असफल, वह 'टी' से बाहर निकलने के कोड प्राप्त होगा।
t0r0X

@LinusArver बाहर निकलने का कोड स्पष्ट नहीं करेगा क्योंकि यह एक कमांड है जो सफल होता है?
carlin.scott

126

गूंगा समाधान: उन्हें एक नामित पाइप (mkfifo) के माध्यम से जोड़ना। फिर कमांड को दूसरा चलाया जा सकता है।

 mkfifo pipe
 tee out.txt < pipe &
 command > pipe
 echo $?

20
इस प्रश्न में यही एकमात्र उत्तर है जो सरल यूनिक्स शेल के लिए भी काम करता है । धन्यवाद!
JamesThomasMoon1979

3
@DaveKennedy: गूंगा के रूप में "स्पष्ट रूप से, बैश वाक्य रचना के जटिल ज्ञान की आवश्यकता नहीं है"
EFraim

10
जबकि बैश के उत्तर अधिक सुरुचिपूर्ण होते हैं जब आपको बैश की अतिरिक्त क्षमताओं का लाभ होता है, तो यह अधिक क्रॉस प्लेटफॉर्म समाधान है। यह भी कुछ ऐसा है जो सामान्य रूप से सोचने के लायक है क्योंकि जब भी आप एक लंबे समय से चलने वाले कमांड का नाम पाइप कर रहे होते हैं तो अक्सर सबसे लचीला तरीका होता है। यह ध्यान देने योग्य है कि कुछ सिस्टम नहीं है mkfifoऔर इसके बजाय आवश्यकता हो सकती है mknod -pअगर मुझे सही याद है।
हरविकिंक

3
कभी-कभी स्टैक ओवरफ्लो पर ऐसे उत्तर दिए जाते हैं कि आप सौ बार अपवित्र हो जाते हैं, इसलिए लोग अन्य काम करना बंद कर देंगे, जिसका कोई मतलब नहीं है, यह उनमें से एक है। धन्यवाद महोदय।
दान चेस

1
मामले में किसी के साथ समस्या है mkfifoया mknod -p: मेरे मामले में पाइप फ़ाइल बनाने के लिए उचित आदेश था mknod FILE_NAME p
करोल गिल

36

एक सरणी है जो आपको एक पाइप में प्रत्येक कमांड की निकास स्थिति देता है।

$ cat x| sed 's///'
cat: x: No such file or directory
$ echo $?
0
$ cat x| sed 's///'
cat: x: No such file or directory
$ echo ${PIPESTATUS[*]}
1 0
$ touch x
$ cat x| sed 's'
sed: 1: "s": substitute pattern can not be delimited by newline or backslash
$ echo ${PIPESTATUS[*]}
0 1

26

यह समाधान बैश विशिष्ट सुविधाओं या अस्थायी फ़ाइलों का उपयोग किए बिना काम करता है। बोनस: अंत में बाहर निकलने की स्थिति वास्तव में एक निकास स्थिति है और फ़ाइल में कुछ स्ट्रिंग नहीं है।

परिस्थिति:

someprog | filter

आप से बाहर निकलने की स्थिति someprogऔर से उत्पादन चाहते हैं filter

यहाँ मेरा समाधान है:

((((someprog; echo $? >&3) | filter >&4) 3>&1) | (read xs; exit $xs)) 4>&1

echo $?

विस्तृत विवरण के लिए unix.stackexchange.com पर एक ही सवाल के लिए मेरा जवाब देखें और सब- हेल्प और कुछ कैविएट के बिना एक विकल्प।


20

एक सब-कमांड में संयोजन PIPESTATUS[0]और exitकमांड निष्पादित करने के परिणामस्वरूप , आप सीधे अपने प्रारंभिक कमांड के रिटर्न मूल्य तक पहुंच सकते हैं:

command | tee ; ( exit ${PIPESTATUS[0]} )

यहाँ एक उदाहरण है:

# the "false" shell built-in command returns 1
false | tee ; ( exit ${PIPESTATUS[0]} )
echo "return value: $?"

तुम्हे दूंगा:

return value: 1


4
धन्यवाद, इसने मुझे निर्माण का उपयोग करने की अनुमति दी: VALUE=$(might_fail | piping)जो मास्टर शेल में PIPESTATUS सेट नहीं करेगा, लेकिन इसकी त्रुटि को सेट करेगा। उपयोग करके: VALUE=$(might_fail | piping; exit ${PIPESTATUS[0]})मैं चाहता हूं कि मैं चाहता हूं।
वाब

@ ओवा, यह वाक्यविन्यास वास्तव में अच्छा लग रहा है, लेकिन मैं इस संदर्भ में भ्रमित हूं कि आपके संदर्भ में 'पाइपिंग' का क्या मतलब है? क्या यह वह जगह है जहाँ कोई 'टी' या जो भी हो सकता है, जो कि may_fail के आउटपुट पर प्रसंस्करण करता है? Ty!
ऐनीइजाइल

1
मेरे उदाहरण में @AnneTheAgile 'पाइपिंग' उन कमांडों के लिए खड़ा है जिनसे आप इरलव नहीं देखना चाहते हैं। उदाहरण के लिए: 'टी', 'ग्रीप', 'सेड' में से एक या किसी भी पाइप्ड कॉम्बिनेशन में से एक ... यह इतना असामान्य नहीं है कि इन पाइपिंग कमांड्स का मतलब किसी बड़े आउटपुट या लॉग आउटपुट से जानकारी को निकालना या निकालना होता है। कमांड: आप तब मुख्य कमांड के इरलेवल में अधिक रुचि रखते हैं (एक मैंने अपने उदाहरण में 'may_fail' कहा है), लेकिन मेरे निर्माण के बिना पूरा असाइनमेंट अंतिम पाइप्ड कमांड के इरव्लव को लौटाता है जो यहां अर्थहीन है। क्या यह स्पष्ट है?
वाब

command_might_fail | grep -v "line_pattern_to_exclude" || exit ${PIPESTATUS[0]}मामले में नहीं लेकिन grep छानने
user1742529

12

इसलिए मैं एक जवाब देना चाहता था जैसे कि लोमना का, लेकिन मुझे लगता है कि मेरा शायद थोड़ा सरल और थोड़ा अधिक लाभकारी शुद्ध-बॉर्न-शेल समाधान है:

# You want to pipe command1 through command2:
exec 4>&1
exitstatus=`{ { command1; printf $? 1>&3; } | command2 1>&4; } 3>&1`
# $exitstatus now has command1's exit status.

मुझे लगता है कि यह अंदर से बाहर से सबसे अच्छी तरह से समझाया गया है - कमांड 1 अपने नियमित आउटपुट को प्रिंटआउट (फाइल डिस्क्रिप्टर 1) पर निष्पादित करेगा और प्रिंट करेगा, फिर एक बार यह पूरा हो जाने पर, प्रिंटफ़ निष्पादित करेगा और icdand1 के एक्जिट कोड को अपने स्टडआउट पर प्रिंट करेगा, लेकिन उस स्टडआउट को पुनर्निर्देशित किया जाएगा। फ़ाइल विवरणक 3।

जबकि कमांड 1 चल रहा है, इसके स्टडआउट को कमांड 2 पर प्रिंट किया जा रहा है (प्रिंटफ का आउटपुट कभी भी कमांड 2 पर नहीं जाता है क्योंकि हम इसे 1 के बजाय फाइल डिस्क्रिप्टर 3 में भेजते हैं, जो कि पाइप पढ़ता है)। फिर हम डिस्क्रिप्टर 4 को फाइल करने के लिए कमांड 2 के आउटपुट को रीडायरेक्ट करते हैं, ताकि वह फाइल डिस्क्रिप्टर 1 से भी बाहर रहे - क्योंकि हम फाइल डिस्क्रिप्टर 1 को थोड़े समय बाद के लिए फ्री चाहते हैं, क्योंकि हम फाइल डिस्क्रिप्टर 3 पर प्रिंटफ आउटपुट को फाइल डिस्क्रिप्टर में वापस लाएँगे। 1 - क्योंकि यह वही है जो कमांड सबस्टेशन (बैकटिक्स) पर कब्जा कर लेगा और इसे वैरिएबल में रखा जाएगा।

जादू का अंतिम बिट यह है कि पहले exec 4>&1हमने एक अलग कमांड के रूप में किया था - यह बाहरी शेल के स्टॉटआउट की एक कॉपी के रूप में फाइल डिस्क्रिप्टर 4 को खोलता है। कमांड प्रतिस्थापन अपने अंदर के कमांड के परिप्रेक्ष्य से मानक आउट पर जो कुछ भी लिखा गया है, उस पर कब्जा कर लेगा - लेकिन चूंकि कमांड प्रतिस्थापन के संबंध में कमांड 2 का आउटपुट डिस्क्रिप्टर 4 को फाइल करने जा रहा है, कमांड प्रतिस्थापन इसे कैप्चर नहीं करता है - हालांकि एक बार यह कमांड प्रतिस्थापन के "आउट" हो जाता है यह प्रभावी रूप से अभी भी स्क्रिप्ट की समग्र फ़ाइल डिस्क्रिप्टर 1 पर जा रहा है।

( exec 4>&1एक अलग कमांड होना चाहिए क्योंकि कमांड प्रतिस्थापन के अंदर फ़ाइल डिस्क्रिप्टर पर लिखने की कोशिश करने पर कई सामान्य गोले इसे पसंद नहीं करते हैं, जो कि "बाहरी" कमांड में खोला जाता है जो प्रतिस्थापन का उपयोग कर रहा है। यह करने के लिए सबसे आसान पोर्टेबल तरीका है।)

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

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

कैविट्स लेमनमा का उल्लेख है, यह संभव है कि कमांड 1 कुछ बिंदुओं पर फ़ाइल डिस्क्रिप्टर 3 या 4 का उपयोग करके समाप्त होगा, इसलिए अधिक मजबूत होने के लिए, आप ऐसा करेंगे:

exec 4>&1
exitstatus=`{ { command1 3>&-; printf $? 1>&3; } 4>&- | command2 1>&4; } 3>&1`
exec 4>&-

ध्यान दें कि मैं अपने उदाहरण में यौगिक आदेशों का उपयोग करता हूं, लेकिन उपधाराएं ( ( )इसके बजाय का उपयोग { }करना भी काम करेगा, हालांकि संभवतः कम कुशल हो सकता है।)

फ़ाइल डिस्क्रिप्टर को इनहेरिट करने वाली प्रक्रिया से इनहेरिट करता है, इसलिए संपूर्ण दूसरी पंक्ति फ़ाइल डिस्क्रिप्टर चार को इनहेरिट करेगी, और उसके बाद कंपाउंड कमांड 3>&1फ़ाइल डिस्क्रिप्टर तीन को इनहेरिट करेगी। इसलिए यह 4>&-सुनिश्चित करता है कि आंतरिक कंपाउंड कमांड फ़ाइल डिस्क्रिप्टर चार 3>&-को इनहेरिट नहीं करेगा , और वॉयल डिस्क्रिप्टर तीन को इनहेरिट नहीं करेगा, इसलिए कमांड 1 को एक 'क्लीनर', अधिक मानक वातावरण मिलता है। तुम भी भीतरी चल सकता 4>&-करने के लिए अगले 3>&-है, लेकिन मैं आंकड़ा क्यों नहीं बस तक संभव हो, इसके दायरे की सीमा।

मुझे यकीन नहीं है कि चीजें कितनी बार फ़ाइल डिस्क्रिप्टर तीन और चार का सीधे उपयोग करती हैं - मुझे लगता है कि ज्यादातर समय प्रोग्राम ऐसे सिस्कल्स का उपयोग करते हैं जो नॉट-ऑन-ऑफ-द-क्षण फ़ाइल डिस्क्रिप्टर लौटाते हैं, लेकिन कभी-कभी कोड डिस्क्रिप्टर 3 को सीधे फाइल करने के लिए लिखते हैं, मैं लगता है (मैं एक प्रोग्राम को देखने के लिए फ़ाइल डिस्क्रिप्टर की जाँच कर सकता हूं कि क्या यह खुला है, और इसका उपयोग कर रहा है या नहीं तो इसके अनुसार अलग-अलग व्यवहार कर रहा है)। इसलिए उत्तरार्द्ध संभवतः सामान्य प्रयोजन के मामलों को ध्यान में रखने और उपयोग करने के लिए सबसे अच्छा है।


अच्छी व्याख्या!
1526 पर सेल्लुवू

6

उबंटू और डेबियन में, आप कर सकते हैं apt-get install moreutils। इसमें एक उपयोगिता कहा जाता है mispipeजो पाइप में पहले कमांड की निकास स्थिति को लौटाता है।


5
(command | tee out.txt; exit ${PIPESTATUS[0]})

@ CODAR के उत्तर के विपरीत, यह पहली कमांड का मूल निकास कोड देता है और सफलता के लिए केवल 0 और विफलता के लिए 127 नहीं है। लेकिन जैसा कि @Chaoran ने बताया कि आप सिर्फ कॉल कर सकते हैं ${PIPESTATUS[0]}। हालांकि यह महत्वपूर्ण है कि सभी कोष्ठक में रखा जाए।


4

बैश के बाहर, आप कर सकते हैं:

bash -o pipefail  -c "command1 | tee output"

यह निंजा लिपियों में उदाहरण के लिए उपयोगी है जहां शेल होने की उम्मीद है /bin/sh


3

पाइपस्टैटस [@] को पाइप कमांड रिटर्न के तुरंत बाद एक सरणी में कॉपी किया जाना चाहिए। PIPESTATUS [@] की कोई भी सामग्री को मिटा देगा। यदि आप सभी पाइप कमांड की स्थिति की जांच करने की योजना बनाते हैं, तो इसे दूसरे सरणी में कॉपी करें। "$?" "$ {PIPESTATUS [@]}" के अंतिम तत्व के समान मूल्य है, और इसे पढ़ने से "$ {PIPESTATUS [@]}" को नष्ट करने लगता है, लेकिन मैंने इसे पूरी तरह से सत्यापित नहीं किया है।

declare -a PSA  
cmd1 | cmd2 | cmd3  
PSA=( "${PIPESTATUS[@]}" )

यदि पाइप सब-शेल में है तो यह काम नहीं करेगा। कि समस्या का समाधान के लिए,
को देखने के backticked आदेश में बैश pipestatus?


3

सादे बाश में ऐसा करने का सबसे सरल तरीका पाइपलाइन के बजाय प्रक्रिया प्रतिस्थापन का उपयोग करना है । कई अंतर हैं, लेकिन वे शायद आपके उपयोग के मामले के लिए बहुत मायने नहीं रखते हैं:

  • पाइप लाइन चलाते समय, सभी प्रक्रियाओं के पूरा होने तक प्रतीक्षा करें।
  • Ctrl-C को बैश करने के लिए भेजना यह एक मुख्य नहीं, बल्कि एक पाइपलाइन की सभी प्रक्रियाओं को मार देता है।
  • pipefailविकल्प और PIPESTATUSचर प्रक्रिया प्रतिस्थापन के लिए अप्रासंगिक हैं।
  • संभवतः अधिक

प्रक्रिया प्रतिस्थापन के साथ, बैश बस प्रक्रिया शुरू करता है और इसके बारे में भूल जाता है, यह भी दिखाई नहीं देता है jobs

मतभेदों को अलग रखा, consumer < <(producer)और producer | consumerअनिवार्य रूप से समतुल्य हैं।

यदि आप फ्लिप करना चाहते हैं कि कौन सी "मुख्य" प्रक्रिया है, तो आप केवल कमांड और प्रतिस्थापन की दिशा को फ्लिप करते हैं producer > >(consumer)। आपके मामले में:

command > >(tee out.txt)

उदाहरण:

$ { echo "hello world"; false; } > >(tee out.txt)
hello world
$ echo $?
1
$ cat out.txt
hello world

$ echo "hello world" > >(tee out.txt)
hello world
$ echo $?
0
$ cat out.txt
hello world

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


1

शुद्ध खोल समाधान:

% rm -f error.flag; echo hello world \
| (cat || echo "First command failed: $?" >> error.flag) \
| (cat || echo "Second command failed: $?" >> error.flag) \
| (cat || echo "Third command failed: $?" >> error.flag) \
; test -s error.flag  && (echo Some command failed: ; cat error.flag)
hello world

और अब दूसरे के catस्थान पर false:

% rm -f error.flag; echo hello world \
| (cat || echo "First command failed: $?" >> error.flag) \
| (false || echo "Second command failed: $?" >> error.flag) \
| (cat || echo "Third command failed: $?" >> error.flag) \
; test -s error.flag  && (echo Some command failed: ; cat error.flag)
Some command failed:
Second command failed: 1
First command failed: 141

कृपया ध्यान दें कि पहली बिल्ली विफल हो जाती है, क्योंकि यह स्टडआउट उस पर बंद हो जाता है। लॉग में विफल आदेशों का क्रम इस उदाहरण में सही है, लेकिन इस पर भरोसा न करें।

यह विधि अलग-अलग आदेशों के लिए stdout और stderr को कैप्चर करने की अनुमति देती है ताकि आप एक त्रुटि होने पर उसे लॉग फ़ाइल में डंप कर सकें, या यदि कोई त्रुटि नहीं हो, तो उसे हटा दें (जैसे dd का आउटपुट)।


1

@ ब्रायन-एस-विल्सन के उत्तर के आधार पर; इस बैश हेल्पर फ़ंक्शन:

pipestatus() {
  local S=("${PIPESTATUS[@]}")

  if test -n "$*"
  then test "$*" = "${S[*]}"
  else ! [[ "${S[@]}" =~ [^0\ ] ]]
  fi
}

इस प्रकार इस्तेमाल किया:

1: get_bad_things को सफल होना चाहिए, लेकिन इसे कोई आउटपुट नहीं देना चाहिए; लेकिन हम इसका उत्पादन देखना चाहते हैं

get_bad_things | grep '^'
pipeinfo 0 1 || return

2: सभी पाइपलाइन सफल होना चाहिए

thing | something -q | thingy
pipeinfo || return

1

बैश के विवरण में खुदाई करने के बजाय बाहरी आदेश का उपयोग करना कभी-कभी सरल और स्पष्ट हो सकता है। पाइपलाइन , न्यूनतम प्रक्रिया स्क्रिप्टिंग भाषा के क्रियान्वयन से , दूसरी कमांड * के रिटर्न कोड के साथ बाहर निकलती है, जैसे कि एक shपाइपलाइन करता है, लेकिन इसके विपरीत sh, यह पाइप की दिशा को उलटने की अनुमति देता है, ताकि हम निर्माता के रिटर्न कोड को कैप्चर कर सकें प्रक्रिया (नीचे सभी shकमांड लाइन पर है, लेकिन execlineस्थापित के साथ ):

$ # using the full execline grammar with the execlineb parser:
$ execlineb -c 'pipeline { echo "hello world" } tee out.txt'
hello world
$ cat out.txt
hello world

$ # for these simple examples, one can forego the parser and just use "" as a separator
$ # traditional order
$ pipeline echo "hello world" "" tee out.txt 
hello world

$ # "write" order (second command writes rather than reads)
$ pipeline -w tee out.txt "" echo "hello world"
hello world

$ # pipeline execs into the second command, so that's the RC we get
$ pipeline -w tee out.txt "" false; echo $?
1

$ pipeline -w tee out.txt "" true; echo $?
0

$ # output and exit status
$ pipeline -w tee out.txt "" sh -c "echo 'hello world'; exit 42"; echo "RC: $?"
hello world
RC: 42
$ cat out.txt
hello world

उपयोग pipelineकरने से देशी बैश पाइपलाइनों में समान अंतर होता है क्योंकि उत्तर # 43972501 में उपयोग की गई बैश प्रक्रिया प्रतिस्थापन ।

* pipelineजब तक कोई त्रुटि न हो, वास्तव में बाहर नहीं निकलें। यह दूसरी कमांड में निष्पादित होता है, इसलिए यह दूसरी कमांड है जो रिटर्निंग करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.