यदि आप वास्तव में नहीं चाहते हैं कि दूसरा कमांड तब तक आगे बढ़े जब तक कि पहला सफल होने के लिए नहीं जाना जाता है, तो आपको संभवतः अस्थायी फ़ाइलों का उपयोग करने की आवश्यकता है। इसका सरल संस्करण है:
tmp=${TMPDIR:-/tmp}/mine.$$
if ./a > $tmp.1
then
if ./b <$tmp.1 >$tmp.2
then
if ./c <$tmp.2
then : OK
else echo "./c failed" 1>&2
fi
else echo "./b failed" 1>&2
fi
else echo "./a failed" 1>&2
fi
rm -f $tmp.[12]
'1> और 2' पुनर्निर्देशन भी संक्षिप्त किया जा सकता है '> और 2'; हालाँकि, MKS शेल के एक पुराने संस्करण ने पूर्ववर्ती '1' के बिना त्रुटि पुनर्निर्देशन को गलत कर दिया है, इसलिए मैंने उम्र के लिए विश्वसनीयता के लिए उस अस्पष्ट अधिसूचना का उपयोग किया है।
यदि आप किसी चीज को बाधित करते हैं तो यह लीक हो जाती है। बम प्रूफ (अधिक या कम) शेल प्रोग्रामिंग का उपयोग करता है:
tmp=${TMPDIR:-/tmp}/mine.$$
trap 'rm -f $tmp.[12]; exit 1' 0 1 2 3 13 15
...if statement as before...
rm -f $tmp.[12]
trap 0 1 2 3 13 15
पहली ट्रैप लाइन कहती है 'कमांड्स चलाएं' rm -f $tmp.[12]; exit 1
'जब कोई भी सिग्नल 1 SIGHUP, 2 SIGINT, 3 SIGQUIT, 13 SIGPIPE, या 15 SIGTERM होते हैं, या 0 (जब शेल किसी भी कारण से बाहर निकलता है)। यदि आप एक शेल स्क्रिप्ट लिख रहे हैं, तो अंतिम ट्रैप को केवल 0 पर जाल को हटाने की आवश्यकता है, जो शेल एग्जिट ट्रैप है (आप इस तरह से अन्य संकेतों को छोड़ सकते हैं क्योंकि प्रक्रिया वैसे भी समाप्त होने वाली है)।
मूल पाइपलाइन में, 'ग' के लिए 'बी' से डेटा पढ़ना संभव है, इससे पहले कि 'ए' समाप्त हो गया है - यह आमतौर पर वांछनीय है (यह उदाहरण के लिए कई कोर काम करने के लिए देता है)। यदि 'b' एक 'सॉर्ट' चरण है, तो यह लागू नहीं होगा - 'b' को अपना कोई भी आउटपुट उत्पन्न करने से पहले उसके सभी इनपुट को देखना होगा।
यदि आप पता लगाना चाहते हैं कि कौन सी कमांड विफल है, तो आप उपयोग कर सकते हैं:
(./a || echo "./a exited with $?" 1>&2) |
(./b || echo "./b exited with $?" 1>&2) |
(./c || echo "./c exited with $?" 1>&2)
यह सरल और सममित है - यह 4-भाग या एन-भाग पाइपलाइन तक विस्तारित करने के लिए तुच्छ है।
'सेट-ई' के साथ सरल प्रयोग से कोई मदद नहीं मिली।
&&|
जिसका अर्थ होगा "केवल पाइप जारी रखें यदि पूर्ववर्ती आदेश सफल था"। मुझे लगता है कि आप भी हो सकते हैं,|||
जिसका अर्थ होगा "पाइप जारी रखें यदि पूर्ववर्ती आदेश विफल हो गया" (और संभवतः बैश 4 की तरह त्रुटि संदेश को पाइप कर सकता है|&
)।