मैं कैसे प्राप्त कर सकता हूं
cmd >> file1 2>&1 1>>file2
यही है, stdout और stderr को एक फ़ाइल (file1) पर पुनर्निर्देशित करना चाहिए और केवल stdout (file2) को दूसरे (दोनों परिशिष्ट मोड में) पर पुनर्निर्देशित करना चाहिए?
मैं कैसे प्राप्त कर सकता हूं
cmd >> file1 2>&1 1>>file2
यही है, stdout और stderr को एक फ़ाइल (file1) पर पुनर्निर्देशित करना चाहिए और केवल stdout (file2) को दूसरे (दोनों परिशिष्ट मोड में) पर पुनर्निर्देशित करना चाहिए?
जवाबों:
समस्या यह है कि जब आप अपने आउटपुट को रीडायरेक्ट करते हैं, तो यह अगले रीडायरेक्ट के लिए उपलब्ध नहीं होता है। tee
दूसरे पुनर्निर्देशन के लिए आउटपुट रखने के लिए आप एक सबशेल में पाइप कर सकते हैं :
( cmd | tee -a file2 ) >> file1 2>&1
या यदि आप टर्मिनल में आउटपुट देखना पसंद करते हैं:
( cmd | tee -a file2 ) 2>&1 | tee -a file1
पहले के stderr को जोड़ने से बचने के tee
लिए file1
, आपको अपनी कमांड के stderr को कुछ फ़ाइल डिस्क्रिप्टर (जैसे 3) में रीडायरेक्ट करना चाहिए, और बाद में इसे फिर से stdout में जोड़ें:
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(साभार @ फ्रा-सान)
के साथ zsh
:
cmd >& out+err.log > out.log
परिशिष्ट मोड में:
cmd >>& out+err.log >> out.log
में zsh
, और बशर्ते mult_ios
विकल्प को अक्षम नहीं किया गया है, जब एक फाइल डिस्क्रिप्टर (यहां 1) को लिखने के लिए कई बार पुनर्निर्देशित किया जाता है, तो शेल tee
सभी लक्ष्यों के आउटपुट को डुप्लिकेट करने के लिए एक अंतर्निहित बनाता है।
cmd >& file1 > file2
आप कर सकते हैं: टैग stdout (एक UNBUFFERED sed का उपयोग करते हुए, यानी:), sed -u ...
stderr भी stdout (untagged के रूप में जाना जाता है, क्योंकि यह उस टैगिंग sed के माध्यम से नहीं गया था), और इस प्रकार परिणामी लॉगफ़ाइल में 2 को अलग करने में सक्षम हो।
निम्नलिखित: धीमा है (इसे गंभीरता से अनुकूलित किया जा सकता है, जबकि इसके बजाय एक पर्ल स्क्रिप्ट का उपयोग करने के लिए ..., करते हैं ...; किया; छूट के लिए, जो हर पंक्ति में सब-कमांड और कमांड को जन्म देगा!), अजीब। (ऐसा लगता है कि मुझे एक नाम बदलने वाले स्टैडआउट में 2 {} चरणों की आवश्यकता है और फिर दूसरे में "stderr" के माध्यम से "गिर गया" जोड़ें), लेकिन यह है: एक " अवधारणा का प्रमाण ", जो रखने की कोशिश करेगा आउटपुट का ऑर्डर जितना संभव हो उतना स्टडआउट और स्टेडर का सबसे अधिक:
#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch
#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
# to see if the order of stdout&stderr is kept
#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2
touch existing existing2 existing3
#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs...
# avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.
{
{ for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
} | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
case "$line" in
${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;;
*) printf "%s\n" "$line" >> out_AND_err.file ;;
esac;
done;
# see the results:
grep "^" out.file out_AND_err.file
ls unknown
स्टादर पर कुछ छापने के लिए आप इस तरह के जटिल उपयोग मामले ( ) का उपयोग क्यों करते हैं ? >&2 echo "error"
ठीक हो जाएगा। (2) tee
एक ही बार में कई फ़ाइलों को जोड़ सकते हैं। (३) सिर्फ cat
इसके बजाय क्यों नहीं grep "^"
? (4) आपकी स्क्रिप्ट तब विफल हो जाएगी जब stderr आउटपुट शुरू होता है _stdout_
। (५) क्यों?
ls loop
दोनों आउटपुट और stderr पर, मिश्रित (वैकल्पिक रूप से), एक नियंत्रित क्रम में, ताकि हम जाँच कर सकें कि हम stderout के टैगिंग के बावजूद उस stderr / stdout आदेश को रखा जा सकता है): विष्णु पूंछ, हो सकता है, लेकिन नहीं नियमित पूंछ (पूर्व, ऐक्स पर।)। 3): grep "^" भी दोनों फाइलनाम को दर्शाता है। 4): इसे वेरिएबल द्वारा बदला जा सकता है। 5): पुरानी छूट (पुराने ऑक्स) पुरानी छूट पर काम करती है, जहां मैंने इसका परीक्षण किया (कोई भी उपलब्ध नहीं है)।
uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406
...)
यदि उत्पादन का क्रम होना चाहिए: stdout तो stderr ; केवल पुनर्निर्देशन से कोई हल नहीं है।
Stderr को एक टेम्पोरल फ़ाइल में संग्रहित किया जाना चाहिए
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
विवरण:
एक आउटपुट (एक fd जैसे stdout या stderr) को दो फ़ाइलों पर पुनर्निर्देशित करने का एकमात्र तरीका इसे पुन: उत्पन्न करना है। tee
फ़ाइल डिस्क्रिप्टर सामग्री को पुन: पेश करने के लिए कमांड सही उपकरण है। इसलिए, दो फ़ाइलों पर एक आउटपुट के लिए एक प्रारंभिक विचार का उपयोग करना होगा:
... | tee file1 file2
कि दोनों फ़ाइलों (1 और 2) के लिए टी के स्टड पुन: पेश करता है टी के उत्पादन को अभी भी अप्रयुक्त छोड़ रहा है। लेकिन हमें (उपयोग -a
) संलग्न करना होगा और केवल एक प्रति की आवश्यकता होगी। यह दोनों मुद्दों को हल:
... | tee -a file1 >>file2
tee
Stdout (दोहराने के लिए) के साथ आपूर्ति करने के लिए हमें सीधे कमांड से बाहर stderr का उपभोग करने की आवश्यकता है। एक तरीका है, यदि आदेश महत्वपूर्ण नहीं है (उत्पादन का क्रम होगा (सबसे शायद) उत्पन्न के रूप में संरक्षित किया जाएगा, जो भी आउटपुट पहले संग्रहीत किया जाएगा)। कोई एक:
cmd 2>>file1 | tee -a file2 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
विकल्प 2 केवल कुछ गोले में काम करता है। विकल्प 3 एक अतिरिक्त उपधारा (धीमी) का उपयोग करता है, लेकिन केवल एक बार फ़ाइल नामों का उपयोग करें।
लेकिन अगर stdout पहले होना चाहिए (जो भी ऑर्डर आउटपुट उत्पन्न होता है) हमें इसे अंतिम (पहला समाधान पोस्ट) में दर्ज करने के लिए स्टेंडर को स्टोर करने की आवश्यकता है।
sponge
:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
विविधता के हितों में:
यदि आपका सिस्टम समर्थन करता है /dev/stderr
, तो
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
काम करेगा। के मानक आउटपुट cmd
को स्टडआउट और पाइपलाइन के स्टैडर दोनों को भेजा जाता है। cmd
बाईपास की मानक त्रुटिtee
और पाइपलाइन के स्टैडर से बाहर आती है।
इसलिए
cmd
, औरcmd
इंटरमिक्स होता है।यह उन धाराओं को सही फाइलों में भेजने का एक साधारण मामला है।
इस तरह के लगभग किसी भी दृष्टिकोण के साथ ( स्टीफन के उत्तर सहित ),
file1
आदेश से बाहर लाइनें मिल सकती हैं।
out+err
औरout
यहाँ मतलब है। फ़ाइल नाम? धाराओं को पुनर्निर्देशित किया जाना है?