बैश के साथ, मैं किसी अन्य प्रक्रिया में मानक त्रुटि को कैसे पाइप कर सकता हूं?


137

यह अच्छी तरह से जाना जाता है कि एक प्रक्रिया के मानक ouput को किसी अन्य प्रक्रिया में कैसे इनपुट किया जाए मानक इनपुट:

proc1 | proc2

लेकिन क्या होगा अगर मैं proc1 की मानक त्रुटि को proc2 पर भेजना चाहता हूं और मानक आउटपुट को उसके वर्तमान स्थान पर जा रहा हूं? आपको लगता है कि bashइनकी तर्ज पर एक कमांड होगी:

proc1 2| proc2

लेकिन, अफसोस, नहीं। क्या इसे करने का कोई तरीका है?


आप इस तरह के एक सरल पुनर्निर्देशन कर सकते हैं rc, जो एक और शेल है। उदाहरण के लिए: proc1 |[2] proc2। क्या यह अच्छा नहीं है? bashहालांकि में नहीं ।
रॉल्फ

जवाबों:


168

प्रक्रिया प्रतिस्थापन भी है । जो एक फाइल के लिए एक प्रक्रिया का विकल्प बनाता है।
आप stderrएक फाइल को इस प्रकार भेज सकते हैं:

process1 2> file

लेकिन आप फ़ाइल के लिए एक प्रक्रिया को निम्नानुसार प्रतिस्थापित कर सकते हैं:

process1 2> >(process2)

यहां एक ठोस उदाहरण दिया गया है जो stderrस्क्रीन पर दोनों को भेजता है और लॉगफ़ाइल में जोड़ता है

sh myscript 2> >(tee -a errlog)

23
यह स्पष्ट रूप से वर्णित प्रश्न का उत्तर देता है और @paxdiablo द्वारा स्वीकृत उत्तर होना चाहिए
mmlb

मैंने यह कोशिश की। यह काम नहीं किया ( weston --help 2> >(less)), और इसने मेरे खोल को तोड़ दिया, मुझे बाहर निकलना पड़ा और वापस लॉग इन करना पड़ा।
रॉल्फ

1
@ रॉल्फ यदि दोनों की weston --helpऔर lessकीबोर्ड इंटरेक्शन की उम्मीद कर रहे हैं, लेकिन उनमें से केवल 1 ही इसे प्राप्त करता है, तो आप एक अजीब स्थिति में हो सकते हैं। grepइसके बजाय कुछ के साथ परीक्षण करने का प्रयास करें । इसके अलावा आप पा सकते हैं कि दोनों माउस / कीबोर्ड इनपुट पश्चिम की बजाय वैसे भी 2 के कमांड पर जा रहे हैं।
बेवुल्फनोडे42

88

आप के लिए निम्न चाल का उपयोग कर सकते स्वैप stdout और stderr। फिर आप बस नियमित पाइप कार्यक्षमता का उपयोग करें।

( proc1 3>&1 1>&2- 2>&3- ) | proc2

बशर्ते stdoutऔर stderrदोनों शुरुआत में एक ही जगह पर इशारा करें, इससे आपको वह मिलेगा जो आपको चाहिए।

x>yफ़ाइल हैंडल को बदलने के लिए बिट क्या करता है xइसलिए यह अब इसकी जानकारी भेजता है कि फाइल हैंडल yवर्तमान में कहां पर है । हमारे विशिष्ट मामले के लिए:

  • 3>&1एक नया हैंडल बनाता है 3जो वर्तमान हैंडल 1(मूल स्टडआउट) को आउटपुट करेगा , बस इसे नीचे अंतिम बुलेट बिंदु के लिए कहीं और सहेजने के लिए।
  • 1>&2वर्तमान हैंडल (मूल stderr) 1को आउटपुट करने के लिए हैंडल (stdout) को संशोधित करता है ।2
  • 2>&3-वर्तमान हैंडल (मूल stdout 2) के लिए आउटपुट ( संभाल ) को संशोधित करता है ( फिर अंत में) के माध्यम से हैंडल बंद कर देता है ।33-

यह प्रभावी रूप से स्वैप कमांड है जिसे आप एल्गोरिदम को सॉर्ट करते हुए देखते हैं:

temp   = value1;
value1 = value2;
value2 = temp;

3
1>&2-केवल उपयोग करने के बजाय यहां उपयोग करने का मूल्य क्या है 1>&2? मुझे समझ में नहीं आता कि हम fd को क्यों बंद करना चाहते हैं 2, अगर हम इसे तुरंत पुनः खोलने / पुन: असाइन करने जा रहे हैं।
dubiousjim

1
@dubiousjim, उस विशेष मामले में कोई फायदा नहीं, मुझे संदेह है कि मैंने इसे लगातार किया है - फ़ाइल हैंडल 3 को बंद करना इसे मुक्त करने के लिए एक अच्छा विचार है।
पैक्सिडाब्लो

अच्छी बात है, @ovgolovin, मैं विश्वास नहीं कर सकता कि किसी ने भी सात महीने में उठाया है क्योंकि मैंने वह संपादन किया है। आपके सुझाव के अनुसार निश्चित किया गया।
पैक्सिडाब्लो

इस के साथ काम करने के लिए gcc का मेक (जो मेरे सिस्टम पर कलर किया गया है) प्राप्त करने की कोशिश कर रहा है "(3> और 1 1> & 2- 2> & 3-) कम -R" जबकि "(ls -al 3> & 1 1> & 2- 2> & 3-) | कम -R "उम्मीद के मुताबिक काम करता है।
unsynchronized

ऐसा लगता है कि आपके स्पष्टीकरण दूसरे दो पुनर्निर्देशों के लिए सामने हैं। 1> और 2- सेट फ़ाइल हैंडल 2 (मूल stderr) को संभालने के लिए 1 (मूल stdout) 2> और 3- सेट फ़ाइल संभाल 3 (प्रतिलिपि किए गए stdout) 2 (मूल stderr) को संभालने के लिए। कृपया मुझे सही करें अगर मैं गलत हूँ। btw, मुझे लगता है कि 2 पर डैश नए stderr डेटा को इस बफर में भेजे जाने से रोकने के लिए है, जबकि इसे stdout के डेटा से पॉप्युलेट किया जा रहा है।
अंजीरथ

70

बैश 4 में यह सुविधा है:

यदि `| & 'का उपयोग किया जाता है, कमांड 1 की मानक त्रुटि पाइप के माध्यम से कमांड 2 के मानक इनपुट से जुड़ी है; यह 2> और 1 के लिए आशुलिपि है | मानक त्रुटि का यह निहित पुनर्निर्देशन कमांड द्वारा निर्दिष्ट किसी भी पुनर्निर्देशन के बाद किया जाता है।

zsh में यह सुविधा भी है।

-

अन्य / पुराने गोले के साथ, बस इसे स्पष्ट रूप से दर्ज करें

फर्स्टकम 2> और 1 | OtherCommand


14
डॉक्स को पढ़ने से, जो मानक त्रुटि और आउटपुट दोनों के रूप में करता है, सिर्फ स्टॉडर के विपरीत, लेकिन यह जानना अच्छा है। बैश 4 को देखना शुरू करने का समय, मुझे लगता है।
paxdiablo

वर्तमान बैश मैनुअल पढ़ता है "यदि | & का उपयोग किया जाता है, तो कमांड का मानक त्रुटि, इसके मानक आउटपुट के अलावा , कमांड 2 के मानक इनपुट से जुड़ा है"। यह स्पष्ट रूप से नहीं है कि ओपी क्या चाहता है।
पीटर -

@ पीटरए. श्नाइडर: ओपी कहता है "मानक उत्पादन को उसके वर्तमान स्थान पर छोड़ दें" जो अस्पष्ट हो सकता है।
अगली सूचना तक रोक दिया गया।

मैं किसी भी अस्पष्टता को देखने में विफल रहा हूं। आपके सुझाव (1) इंगित दो धाराओं। (2) संयुक्त डेटा को कहीं और OtherCommandलिखता है, संभवतः कहीं और। तो यह एक ही डेटा नहीं है, और यह संभवतः कहीं और जा रहा है। यह ओपी की इच्छा के विपरीत है, है ना?
पीटर -

@ पीटरए.साइडर: मानक आउटपुट का वर्तमान स्थान और कहां है? अगर proc1stdout और stderr करने के लिए आउटपुट और आप stderr के stdin proc2(जो कि जहां proc1 के stdout जा रहा है) के लिए जाना चाहते हैं , तो मेरा जवाब है कि पूरा करता है। मैं ओपी क्या वह दे दी पूछा के लिए, शायद क्या नहीं वह मतलब के लिए पूछने के लिए। उसमें संभावित अस्पष्टता निहित है। ओपी ने उत्तर को स्वीकार कर लिया जो स्टैडआउट और स्टैडर को स्वैप करता है जो वह नहीं है जो उसने मांगा था।
अगली सूचना तक रोक दिया गया।

27

स्वैपिंग महान है क्योंकि यह समस्या को हल करता है। बस अगर आपको मूल स्टडआउट की आवश्यकता नहीं है, तो आप इसे इस तरह से कर सकते हैं:

proc1 2>&1 1>/dev/null | proc2

आदेश महत्वपूर्ण है; आप नहीं चाहेंगे:

proc1 >/dev/null 2>&1 | proc1

के रूप में यह सब कुछ पुनर्निर्देशित करेगा /dev/null!


0

इनमें से कोई भी वास्तव में बहुत अच्छा काम नहीं करता था। सबसे अच्छा तरीका मुझे वही करना है जो आप चाहते थे:

(command < input > output) 2>&1 | less

यह केवल उन मामलों के लिए काम करता है जहां commandकीबोर्ड इनपुट की आवश्यकता नहीं होती है। उदाहरण के लिए:

(gzip -d < file.gz > file) 2>&1 | less

gzip त्रुटियों को कम में रखेगा

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