मुझे पता है कि दोनों को एक विशिष्ट फ़ाइल पर रीडायरेक्ट करना संभव है:

./command 1> out.log 2> err.log

या

./command 1>test.log 2>&1

दोनों को एक फाइल में लिखने के लिए। लेकिन मुझे दोनों में से केवल एक को प्रिंट करते समय एक ही फाइल (आउटपुट ऑर्डर को संरक्षित करना) में लिखने का कोई तरीका नहीं पता है। tee बहुत मददगार नहीं है क्योंकि यह दोनों फाइल डिस्क्रिप्टर को प्रिंट करता है।

2
Sebi2020 11 अप्रैल 2020, 03:40
तो दोनों एक फाइल के लिए, लेकिन केवल एक या दूसरे को, टर्मिनल कहें?
 – 
chepner
11 अप्रैल 2020, 03:45
हां बिल्कुल।
 – 
Sebi2020
11 अप्रैल 2020, 04:09

5 जवाब

कंसोल के लिए stdout और फ़ाइल में stdout और त्रुटि?

{ cmd | tee /dev/tty; } &> /tmp/both.log
1
Diego Torres Milano 11 अप्रैल 2020, 05:52
वाह, यह बहुत आसान है, लेकिन मुझे यकीन नहीं था कि सीधे टर्मिनल तक पहुंचना ठीक है या नहीं। अगर मैं टर्मिनल पर stdout के बजाय stderr प्रिंट करना चाहता हूं और दोनों को लॉग फ़ाइल में लिखना चाहता हूं। मुझे लगता है कि यह इस तरह इतना आसान नहीं है, है ना?
 – 
Sebi2020
11 अप्रैल 2020, 13:54
थोड़ा अधिक जटिल लेकिन संभव: { cmd 2> >(tee /dev/tty); } &> /tmp/both.log
 – 
Diego Torres Milano
12 अप्रैल 2020, 01:53

प्रश्न का उत्तर देने के लिए:

कंसोल के लिए stderr और फ़ाइल में stdout और त्रुटि?

{ cmd 3>&1 1>&2 2>&3 | tee /dev/tty; } &> /tmp/both.log

3>&1 1>&2 2>&3 का अर्थ है stdout और stderr की अदला-बदली करना

1
Philippe 11 अप्रैल 2020, 16:48

tee के साथ एक फ़ाइल और दूसरी फ़ाइल में मानक आउटपुट लिखना काफी सरल है:

{ cmd | tee stdout.log; } &> both.log

कंपाउंड कमांड के दोनों डिस्क्रिप्टर को both.log पर पुनर्निर्देशित किया जाता है, लेकिन cmd का मानक आउटपुट पहले tee से stdout.log तक both.log को लिखे जाने से पहले पास किया जाता है। .

एक और दोनों को मानक त्रुटि लिखना अधिक कठिन है।

{ foo 2>&1 1>&3 | tee stderr.log ; } 3>&1 | tee both.log > /dev/null

इसका सही-सही वर्णन करना थोड़ा मुश्किल है। सबसे पहले, कमांड समूह की मानक त्रुटि पर ध्यान नहीं दिया जाता है; इसका मानक आउटपुट tee both.log का पाइप है। लेकिन 3>&1 इसके fd 3 को इसके मानक आउटपुट में कॉपी भी करता है। तो सवाल यह है कि इसमें क्या लिखा जाता है?

कमांड समूह के अंदर, foo का मानक आउटपुट tee stderr.log का पाइप है। 2>&1 उस डिस्क्रिप्टर को tee's मानक त्रुटि की प्रतिलिपि बनाता है, और 1>&3 foo's मानक आउटपुट को इनहेरिट किए गए fd 3 में कॉपी करता है।

2
chepner 11 अप्रैल 2020, 04:03
ठीक है कि काम करता है, लेकिन मैं चाहता था कि कंसोल पर स्टडआउट मुद्रित किया जाए। fd 3 किस फाइल से संबंधित है? क्या मुझे आर्बिटरी फ़ाइल डिस्क्रिप्टर को पुनर्निर्देशन करने की अनुमति है? (जो किसी फ़ाइल को इंगित नहीं कर सकता है)
 – 
Sebi2020
11 अप्रैल 2020, 04:23

उन्हें अलग-अलग फाइलों में लिखना बेहतर होगा, इस मामले में यह बहुत आसान होगा:

cmd 2>/stderr.log| tee -a stdout.log

लेकिन अगर आप सिंगल फाइल चाहते हैं, तो आपको यहां कुछ ट्रिक्स और रीडायरेक्शन के लिए चलने वाली अतिरिक्त प्रक्रिया की आवश्यकता होगी।

1
Saboteur 11 अप्रैल 2020, 04:03

आप कई पुनर्निर्देशन का उपयोग कर सकते हैं:

foo () { echo 1 ; echo 2 >&2 ; }
(( foo | tee >(cat) >&3) &>log ) 3>&1

टी कमांड stdout को डिस्क्रिप्टर 1 (प्रक्रिया प्रतिस्थापन के माध्यम से) और 3 फाइल करने के लिए भेजता है। दोनों stdout और stderr को लॉग पर पुनर्निर्देशित किया जाता है। अंत में, 3, स्टडआउट की प्रति, टर्मिनल को वापस भेज दी जाती है।

वैकल्पिक रूप से, आप प्रक्रिया प्रतिस्थापन के बिना कर सकते हैं, आउटपुट को सीधे लॉग पर पुनर्निर्देशित कर सकते हैं, लेकिन परिशिष्ट के लिए -a और >> का उपयोग करें। आपको लॉग को पहले से साफ़ करना होगा।

: > log; (( foo | tee -a log >&3) 2>> log ) 3>&1
1
choroba 11 अप्रैल 2020, 05:02
यह लॉग फ़ाइल tee: /dev/fd63: Not a directory में निम्न त्रुटि लिखता है
 – 
Sebi2020
11 अप्रैल 2020, 04:22
इससे मेरा काम बनता है। आप किस ओएस का उपयोग कर रहे हैं पर किस बैश संस्करण का उपयोग कर रहे हैं?
 – 
choroba
11 अप्रैल 2020, 04:29
GNU बैश, संस्करण 4.4.19(2)-रिलीज़ (x86_64-pc-msys) (Windows पर mingw)
 – 
Sebi2020
11 अप्रैल 2020, 04:33
:>log; (( foo | tee -a log >&3) 2>> log ) 3>&1 के बारे में क्या?
 – 
choroba
11 अप्रैल 2020, 04:38
यह चलने लगा ! अच्छा है, लेकिन मुझे लगता है कि यह आउटपुट ऑर्डर को संरक्षित नहीं करता है। 2 को 1 से पहले लिखा जाता है और वैकल्पिक आउटपुट जैसे 1 2 1 2 1 के बारे में क्या लिखा जाता है।
 – 
Sebi2020
11 अप्रैल 2020, 04:52