2012-01-12 11 views
11

मुझे एक यूनिक्स कमांड लाइन एप्लिकेशन से सही रिटर्न कोड कैसे प्राप्त होता है जब मैंने इसे किसी अन्य कमांड के माध्यम से पाइप किया है?पाइप कमांड आउटपुट, लेकिन त्रुटि कोड

विस्तार में, यहाँ की स्थिति है:

$ tar -cEvhf - -I ${sh_tar_inputlist} | gzip -5 -c > ${sh_tar_file} -- when only the tar command fails $?=0 
$ echo $? 
0 

और, मैं क्या देखना चाहते हैं है:

$ tar -cEvhf - -I ${sh_tar_inputlist} 2>${sh_tar_error_file} | gzip -5 -c > ${sh_tar_file} 
$ echo $? 
1 

किसी को भी यह कैसे पूरा करने के लिए पता है?

+0

'$? 'त्रुटि कोड रखता है। आप इसे एक चर में सहेज सकते हैं। –

+1

मुझे इंटरमीडिएट कमांड का रिटर्न कोड सहेजने की ज़रूरत है, न कि आखिरी कमांड। – SamiBOB

उत्तर

3

केवल पॉज़िक्स खोल का उपयोग करके एक सामान्य समाधान है और कोई अस्थायी फ़ाइलें नहीं:

पाइपलाइन से शुरू: foo | बार | baz

exec 4>&1 
error_statuses=`((foo || echo "0:$?" >&3) | 
     (bar || echo "1:$?" >&3) | 
     (baz || echo "2:$?" >&3)) 3>&1 >&4` 
exec 4>&- 

$ error_statuses किसी भी स्थिति कोड बताने के लिए जो आदेश प्रत्येक स्थिति उत्सर्जित, विफल रही प्रक्रियाओं सूचकांक यादृच्छिक क्रम में शामिल हैं।

# if "bar" failed, output its status: 
echo $error_statuses | grep '1:' | cut -d: -f2 

# test if all commands succeeded: 
test -z "$error_statuses" 

# test if the last command succeeded: 
echo $error_statuses | grep '2:' >/dev/null 
4

$PIPESTATUS पर देखें जो एक सरणी चरणीय होल्डिंग स्थिति है। तो ${PIPESTATUS[0]} पाइप में पहले कमांड की निकास स्थिति, ${PIPESTATUS[1]} दूसरे आदेश की निकास स्थिति, और इसी तरह से है।

उदाहरण के लिए:

$ tar -cEvhf - -I ${sh_tar_inputlist} | gzip -5 -c > ${sh_tar_file} 
$ echo ${PIPESTATUS[0]} 

बाहर मुद्रित करने के लिए सभी स्थितियों का उपयोग करें:

$ echo ${PIPESTATUS[@]} 
+1

Thx, लेकिन मैं अपनी स्क्रिप्ट के साथ बैश का उपयोग नहीं करता हूं। मैं #!/Bin/sh – SamiBOB

+0

@ डोगबेन के साथ काम करता हूं, '$ {PIPESTATUS [*]}' और '$ {PIPESTATUS [@]}' के बीच कोई अंतर है? मैं हमेशा पूर्व का उपयोग करता हूं ... – fge

+2

डाउनवॉटेड, $ PIPESTATUS ** POSIX में मौजूद नहीं है **। –

10

उपयोग ${PIPESTATUS[0]} पाइप में पहली आदेश के निकास स्थिति पाने के लिए। यदि आपका खोल $PIPESTATUS का समर्थन नहीं करता

जानकारी के लिए, अन्य तरीकों के लिए http://tldp.org/LDP/abs/html/internalvariables.html#PIPESTATUSREF

भी देखें http://cfajohnson.com/shell/cus-faq-2.html देखते हैं।

+2

डाउनवॉटेड, $ PIPESTATUS ** POSIX में मौजूद नहीं है **। –

1

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

 
#!/bin/sh 

trap 'rm -rf $TMPDIR' 0 
TMPDIR=$(mktemp -d) 
mkfifo ${FIFO=$TMPDIR/fifo} 

cmd1 > $FIFO & 
cmd2 < $FIFO 
wait $! 
echo The return value of cmd1 is $? 

(ठीक है, यदि आप एक फीफो का उपयोग करने की जरूरत नहीं है तुम आदेशों पाइप के शुरू में हो सकता है एक स्थिति गूंज। परिवर्तनीय और eval कि मुख्य खोल में, सभी जगहों पर फ़ाइल वर्णनकर्ताओं को पुनर्निर्देशित करना और मूल रूप से चीजों की जांच करने के लिए पीछे की तरफ झुकना, लेकिन एक फीफो का उपयोग करना बहुत आसान है।)

+0

हैलो, मैंने इस तकनीक की कोशिश की है लेकिन यह काम करने के लिए सीम नहीं है: मैंने परीक्षण किया:/usr/bin/tar-cMEvhf - -I/tmp/test।tmp> $ फीफो और gzip -5 -c < $FIFO > /tmp/test.bkz $ प्रतीक्षा करें! गूंज cmd1 का वापसी मूल्य $ है? – SamiBOB

+0

आपको क्या त्रुटि मिली? –

+0

जब भी cmd1 विफल रहता है, $? = 0 – SamiBOB

संबंधित मुद्दे