एक bash स्क्रिप्ट में stderr संदेशों को दबाएं


48

निम्नलिखित पर विचार करें (थोड़ा मूर्खतापूर्ण) स्क्रिप्ट नाम 'test1.sh':

#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep

जब मैं इसे चलाता हूं, तो मुझे न केवल प्रतिध्वनि का उत्पादन मिलता है, बल्कि स्टाफ़ पर नींद की मौत की मार की सूचना है:

$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5:  3551 Terminated              sleep 10

इस मामले में, मैं प्रिंटआउट को stderr में दबाना चाहूंगा। मुझे पता है कि मैं इसे कमांड लाइन पर कर सकता हूं, जैसे कि:

$ ./test1.sh 2> /dev/null

... लेकिन क्या स्क्रिप्ट के भीतर से इसे दबाने का कोई तरीका है ? (मुझे पता है कि मैं इसे दूसरी स्क्रिप्ट में लपेट सकता हूं और रैपर इसे पुनर्निर्देशित कर सकता है, लेकिन कुछ आसान होना चाहिए ...)


क्या आपने पिल्ले नींद के बाद 2> / dev / null जोड़ने की कोशिश की?
राहुल

@ इहुल: हाँ मैंने किया - pkill संदेश उत्पन्न नहीं कर रहा है, बैश है।
fearless_fool

मैंने pkill की जगह किल का इस्तेमाल किया और मुझे stderr नहीं मिला। अजीब ..
राहुल

@ प्रह्लाद: क्या यह एक बिल्ट इन नॉन-बिल्ट चीज़ हो सकता है? क्या आपने इसे pkill के साथ भी आज़माया?
fearless_fool

हाँ, मेरा मानना ​​है कि यह है। मुझे pkill के साथ एक ही त्रुटि मिलती है, लेकिन मारने के साथ नहीं। किल का उपयोग करते समय, मैंने खरीद नाम के बजाय पिड का उपयोग किया।
राहुल

जवाबों:


72

आप सही हे; pkill संदेश उत्पन्न नहीं कर रहा है, bash है। आप सुझाव दें कि

$ ./test1.sh 2> /dev/null

एक संभावित समाधान है। जैसा कि यूवीवी बताता है, स्क्रिप्ट के भीतर से बराबर कार्रवाई होती है

exec 2> /dev/null

यह स्क्रिप्ट के लिए स्टैडर /dev/null को इस कथन से पुनर्निर्देशित करता है जब तक कि इसे वापस नहीं बदल दिया जाता। इसे वापस बदलने के अनाड़ी तरीके शामिल हैं

exec 2> /dev/tty

जो टर्मिनल के लिए stderr को पुनर्निर्देशित करता है। यह संभवतः (लेकिन जरूरी नहीं) है जहां यह मूल रूप से था।

या

exec 2>&1

जो stderr को stdout के समान बनाता है, और गलत होने की संभावना है।

एक और अधिक विश्वसनीय तरीका है

3> और 2 निष्पादित करें
exec 2> / dev / null
(वह सामान करें जहाँ आप stderr नहीं देखना चाहते हैं।) 
2> और 3 निष्पादित करें

जो फ़ाइल डिस्क्रिप्टर 3 में मूल stderr को बचाता है, और बाद में इसे पुनर्स्थापित करता है।

सिर्फ मौत की प्रक्रिया की घोषणा को दबाने के अन्य तरीकों में शामिल हैं

(sleep 10 & pkill sleep) 2> /dev/null

तथा

{ sleep 10 & pkill sleep;} 2> /dev/null

जो केवल समूहीकृत कमांड के लिए स्टाडर बदलते हैं।


यह इतना शानदार, विस्तृत जवाब है। शुक्रिया जनाब!
कीनन लॉरेंस

क्या किसी भी तरह के खतरों को बचाने stdinऔर stderrनई फाइल के विवरणों से जुड़े हैं, मूल विवरणकों को भेजने /dev/nullऔर फिर उन्हें पुनर्स्थापित करने के लिए?
अलेक्सज मगुरा

ठीक है, मुझे लगता है कि, यदि आप एक प्रोग्राम चलाते हैं जो (आपके लिए अनजान) ने डिस्क्रिप्टर 3 (या 4) में दर्ज करने के लिए लिखा है, तो यह ऑपरेशन सामान्य परिस्थितियों में विफल हो जाएगा। लेकिन कार्यक्रम को विफलता की अनदेखी करने और इसे रिपोर्ट किए बिना आगे बढ़ाने के लिए लिखा जा सकता है; तब आपको कभी पता नहीं चलेगा। लेकिन अगर आपकी फाइल डिस्क्रिप्टर 1 (या 2) फाइल डिस्क्रिप्टर 3 (या 4) पर "पार्क की गई" थी, तो वह प्रोग्राम अचानक आपकी स्क्रिप्ट के स्टडआउट या स्टडर पर लिख जाएगा। लेकिन यह एक बहुत ही विवादित उदाहरण है, और अभी भी न्यूनतम खतरा है। क्या आपके मन में कुछ था?
स्कॉट

1
Fwiw, मैं स्कॉट वर्गीकृत किया आदेश दृष्टिकोण, यानी पक्ष{ sleep 10 & pkill sleep;} 2> /dev/null
fearless_fool

9

के अनुसार इस आप निम्नलिखित की तरह कुछ कर सकता है:

#!/bin/bash
exec 2>/dev/null
ls -al test
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.