स्टडआउट के बिना पाइप स्टेटर को कैसे पाइप करें


24

मैं मानक आउट स्ट्रीम को पाइप किए बिना मानक त्रुटि स्ट्रीम को कैसे पाइप करूं?

मुझे पता है कि यह कमांड काम करता है, लेकिन यह मानक बाहर भी लिखता है।

Command 2>&1 | tee -a $LOG

मुझे केवल मानक त्रुटि कैसे मिलती है?

नोट: मैं जो चाहता हूं, वह सिर्फ एक लॉग में stderr स्ट्रीम लिखने और कंसोल के लिए stderr और stdout दोनों लिखने के लिए है।

जवाबों:


26

ऐसा करने के लिए, stderr और stdout को स्विच करने के लिए एक अतिरिक्त फ़ाइल डिस्क्रिप्टर का उपयोग करें:

find /var/log 3>&1 1>&2 2>&3 | tee foo.file

मूल रूप से, यह काम करता है, या कम से कम मुझे लगता है कि यह काम करता है, निम्नानुसार है:
पुन: दिशाओं का मूल्यांकन बाएं से दाएं किया जाता है।

3>&1 एक नया फ़ाइल डिस्क्रिप्टर बनाता है, 3 fd 1 (stdout) का एक डुप्लिकेट (कॉपी)।

1>&2 स्टडआउट (1) fd 2 का डुप्लिकेट (stderr)

2>&3 एफडी 2, 3 का डुप्लिकेट (कॉपी) बनाएं, जिसे पहले स्टडआउट की कॉपी बनाया गया था।

तो अब stderr और stdout स्विच किए जाते हैं।

| tee foo.file टी फ़ाइल डिस्क्रिप्टर 1 को डुप्लिकेट करता है जिसे स्टडर में बनाया गया था।


ओह, ksh के साथ परीक्षण नहीं किया गया है, हालांकि बैश के साथ काम करता है ...
काइल ब्रांट

धन्यवाद, ksh में भी काम करता है। मुझे लगता है कि ज्यादातर पाइप और स्ट्रीम चीजें पॉज़िक्स स्टैंडर्ड हैं।
सी। रॉस

"कॉपी" वास्तव में सही नहीं है - @ Guasqueño का उत्तर देखें।
काइल ब्रान्ड

यह भी विंडोज में tee.exeस्थापित :) के साथ काम करता है :
एकॉर्न

13

काइल की यूनिक्स / लिनक्स कमांड STDERR को STDOUT के साथ बदलने का काम करती है; हालाँकि स्पष्टीकरण बहुत सही नहीं है। रीडायरेक्टिंग ऑपरेटर कोई भी नकल या नकल नहीं करते हैं, वे प्रवाह को एक अलग दिशा में पुनर्निर्देशित करते हैं।

अस्थायी रूप से 3> & 1 को समाप्त करके काइल की कमान को फिर से शुरू करना, इस अवधारणा को समझना आसान बना देगा:

find /var/log  1>&2  2>&3  3>&1  

इस तरह से लिखा गया है, लेकिन लिनक्स एक त्रुटि प्रदर्शित करेगा क्योंकि और 3 अभी तक मौजूद नहीं है क्योंकि यह 3> और 1 से पहले स्थित है। 3> कुछ यह घोषित करने (परिभाषित) करने का एक तरीका है कि हम एक तीसरे पाइप का उपयोग करने जा रहे हैं, इसलिए इसे उस पाइप में पानी प्रवाहित करने से पहले इसे स्थित करना होगा, उदाहरण के लिए जिस तरह से काइल ने इसे लिखा था। इस अन्य तरीके को केवल मनोरंजन के लिए आज़माएं:

((echo "STD1";  anyerror "bbbb"; echo "STD2" ) 3>&1 4>&2 1>&4 2>&3) > newSTDOUT 2> newSTDERR

कॉपियाँ करने का तरीका नहीं होना शर्म की बात है। आप एक ही कमांड में "3> और 1 3> & 2" जैसी चीजें नहीं कर सकते, क्योंकि लिनक्स केवल पहले वाले का उपयोग करेगा और दूसरे को खारिज कर देगा।

मैंने (अभी तक) एक फ़ाइल में त्रुटि और नियमित आउटपुट दोनों को भेजने का एक तरीका नहीं पाया है और एक कमांड के साथ स्टैंडर आउटपुट में त्रुटि की एक प्रति भी भेजें। उदाहरण के लिए, मेरे पास एक क्रॉन नौकरी है जो मैं चाहता हूं कि दोनों आउटपुट (त्रुटि और मानक) एक लॉग फ़ाइल पर जाएं और त्रुटि को भी बाहर जाने के लिए एक ईमेल संदेश मेरे ब्लैकबरी को भेजा जाए। मैं इसे "टी" का उपयोग करके दो आदेशों के साथ कर सकता हूं लेकिन फ़ाइल में नियमित आउटपुट लाइन के बीच त्रुटि सही क्रम में नहीं दिखाई देती है। यह बदसूरत तरीका है जिससे मैंने समस्या का समाधान किया:

((echo "STD1"; sdfr "bbbb"; echo "STD2" ) 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1

ध्यान दें कि मुझे दो बार लॉग 1 का उपयोग करना है और मुझे दोनों मामलों में संलग्न करना होगा, एफआईआर "टी" कमांड के लिए "-ए" विकल्प का उपयोग करके और दूसरा ">>" का उपयोग करके।

एक बिल्ली log1 कर आप निम्नलिखित मिलता है:

STD1
STD2
-bash: sdfr: command not found

ध्यान दें कि त्रुटि दूसरी पंक्ति में नहीं दिखनी चाहिए जैसी कि होनी चाहिए।


बहुत बढ़िया सुधार!
काइल ब्रान्ड

कई बार FD को पुनर्निर्देशित करने में सक्षम होने के लिए zsh और mult_iosविकल्प (डिफ़ॉल्ट रूप से) देखें।
टॉम हेल

2

ksh (pdksh) के लिए मैन पेज के अनुसार, आप बस कर सकते हैं:

कमांड 2> और 1> / देव / अशक्त | बिल्ली-एन

यानी स्टडआउट के लिए स्टाइपर, रीडायरेक्ट स्टडआउट टू / देव / नल, फिर पाइप में 'कैट-एन'

मेरे सिस्टम पर pdksh पर काम करता है:

$ इरोरोचो () {इको "$ @"> & 2 ;;

$ इरोचो फू
foo

$ इरोचो फू> / देव / नल # अभी भी स्टडआउट के साथ प्रदर्शित होना चाहिए
foo

$ इरूरोचो फू 2> & 1> / देव / नल | बिल्ली-एन
     1 फू
$   

व्यस्त बॉक्स के साथ भी काम करता है
जी

1

मैं इसे यू की तरह चल रहा था जब से मैं भी इसकी जरूरत है और अपने आदेश को परिष्कृत किया। अब मेरे लिए यह डेबियन निचोड़ पर बैश 3.2 का उपयोग करके सही काम करता है

(echo "foo" 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1 >> log2

जबकि log1 लॉग stdout और stderr और log2 केवल stderr को लॉग करता है और इसके अलावा कुछ भी स्क्रीन पर नहीं आता है।

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