2> और 1> आउटपुट.लॉग और 2> और 1 के बीच अंतर | टी आउटपुट


35

मैं निम्नलिखित दो आज्ञाओं के बीच अंतर जानना चाहता था

2>&1 > output.log 

तथा

2>&1 | tee output.log

मैंने देखा कि मेरे एक सहकर्मी ने पुनर्निर्देशन के लिए दूसरे विकल्प का उपयोग किया है। मुझे पता है कि 2> और 1 क्या करता है, मेरा एकमात्र सवाल यह है कि टी का उपयोग करने का उद्देश्य क्या है जहां एक सरल पुनर्निर्देशन ">" ऑपरेटर का उपयोग किया जा सकता है?

जवाबों:


11

दोनों आज्ञाओं को अलग-अलग देखना:

utility 2>&1 >output.log 

यहां, चूंकि पुनर्निर्देशन को बाएं से दाएं तरीके से संसाधित किया जाता है, इसलिए मानक त्रुटि स्ट्रीम को पहले जहां मानक आउटपुट स्ट्रीम (संभवतः कंसोल) में जाता है, और फिर मानक आउटपुट स्ट्रीम को एक फ़ाइल पर पुनर्निर्देशित किया जाएगा। मानक त्रुटि स्ट्रीम को उस फ़ाइल पर पुनर्निर्देशित नहीं किया जाएगा।

इसका दृश्यमान प्रभाव यह होगा कि आपको स्क्रीन पर मानक त्रुटि पर क्या उत्पादन होता है और फ़ाइल में मानक आउटपुट पर क्या उत्पादन होता है।

utility 2>&1 | tee output.log

यहां, आप मानक त्रुटि को मानक आउटपुट स्ट्रीम के समान स्थान पर रीडायरेक्ट करते हैं। इसका मतलब यह है कि दोनों धाराओं को teeएकल इंटरलिग्ड आउटपुट स्ट्रीम के रूप में उपयोगिता के लिए पाइप किया जाएगा , और यह मानक आउटपुट डेटा द्वारा दी गई फ़ाइल में सहेजा जाएगा tee। डेटा को इसके द्वारा teeकंसोल में पुन: पेश किया जाएगा (यह वही teeकरता है, यह डेटा स्ट्रीम को डुप्लिकेट करता है)।

इनमें से कौन सा प्रयोग किया जाता है यह इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं।

ध्यान दें कि आप दूसरी पाइपलाइन के प्रभाव को सिर्फ >(जैसा कि utility >output.log 2>&1, जो फ़ाइल में मानक आउटपुट और त्रुटि दोनों को बचाएगा) के साथ पुन: उत्पन्न नहीं कर पाएंगे । आपको teeकंसोल के साथ-साथ आउटपुट फ़ाइल में डेटा प्राप्त करने के लिए उपयोग करने की आवश्यकता होगी ।


अतिरिक्त नोट्स:

पहले कमांड का दृश्य प्रभाव,

utility 2>&1 >output.log 

जैसा होगा वैसा ही होगा

utility >output.log

यानी, मानक आउटपुट फ़ाइल में जाता है और मानक त्रुटि कंसोल पर जाती है।

यदि उपरोक्त प्रत्येक आदेश के अंत में एक और प्रसंस्करण कदम जोड़ा गया था, तो एक बड़ा अंतर होगा:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

पहली पाइपलाइन में, more_stuffमूल मानक धारा utilityडेटा से उसके मानक इनपुट डेटा के रूप में मूल रूप से क्या मिलेगा , जबकि दूसरी पाइपलाइन में, क्योंकि यह केवल मानक मानक धारा है जिसे कभी पाइप में भेजा जाता है, more_stuffपाइपलाइन के हिस्से को कुछ भी नहीं मिलेगा। इसके मानक इनपुट पर पढ़ने के लिए।


आदेश "के साथ utility 2>&1 | tee output.log, आप कहना है कि 1 के बाद से टी करने के लिए निर्देशित किया जा रहा है, 2 के साथ-साथ है मतलब है। के बाद से टी धारा डुप्लिकेट, उत्पादन दोनों के साथ-साथ कंसोल पर प्रदर्शित किया जाता है के रूप में फाइल करने के लिए लिखा? इसलिए बीच का अंतर utility 2>&1 > output.logऔर utility 2>&1 | tee output.logहै teeमें यह धारा डुप्लिकेट चाहेंगे कि सही हो।?
प्रेरित

के उदाहरण के साथ utility 2>&1 > output.log | more_stuffऔर utility >ouput.log| more_stuff , is the difference that more_stuff` कंसोल के लिए मानक त्रुटि आउटपुट इनपुट के रूप में है more_stuff? चूंकि दूसरे उदाहरण में, कंसोल के लिए कोई आउटपुट नहीं है, इसलिए अनिवार्य रूप से कोई इनपुट नहीं है more_stuff? यदि हाँ, तो यह स्पष्ट नहीं है कि पूर्ववर्ती पैराग्राफ़ पर आप ध्यान दें कि मानक आउटपुट फ़ाइल में जाता है और मानक त्रुटि कंसोल पर जाती है।
प्रेरित

@ टिप्पणी आपकी पहली टिप्पणी मुझे सही लगती है, हाँ। दूसरी टिप्पणी के रूप में: पहले आदेश में, मूल रूप से अपनी त्रुटि स्ट्रीम (लेकिन जो मानक आउटपुट पर पुनर्निर्देशित की गई थी) को भेजा more_stuffजाएगा । इसलिए नहीं कि यह कंसोल पर खत्म होता अगर ऐसा नहीं था, लेकिन क्योंकि यह मानक आउटपुट स्ट्रीम में जा रहा है । दूसरे कमांड में, पाइप के बायीं ओर से कोई मानक आउटपुट नहीं होने के कारण कुछ भी नहीं मिलता है । से त्रुटि धारा अभी भी 2 डी कमांड में कंसोल पर समाप्त होगी। utilitymore_stuffmore_stuffutility
Kusalananda

धन्यवाद। क्या इसका मतलब यह है कि क्योंकि कमांड utility > output.log | more_stuffमानक आउटपुट स्ट्रीम में आउटपुट में मानक त्रुटि बिंदु से परिणाम नहीं देता है?
प्रेरित

@Motized चूंकि बाएं हाथ की तरफ मानक आउटपुट पर कुछ भी उत्पन्न नहीं होता है (इसे पुनर्निर्देशित किया गया है), पाइप पर कोई डेटा नहीं भेजा जाएगा।
Kusalananda

24

संपादकीय नोट

कृपया इस उत्तर पर टिप्पणियों को पढ़ना सुनिश्चित करें - अपमानजनक


मूल उत्तर

2>&1 >output.logइसका मतलब है कि पहले सभी फाइल हैंडल 2 स्टैण्डर्ड (स्टैंडर्ड एरर) को हैंडल 1 (स्टैंडर्ड आउटपुट) को भेजना शुरू करें, फिर उस फाइल को भेजें output.log। दूसरे शब्दों में, लॉग फ़ाइल में मानक त्रुटि और मानक आउटपुट भेजें।

2>&1 | tee output.log2>&1बिट के साथ समान है , यह मानक आउटपुट स्ट्रीम पर मानक आउटपुट और मानक त्रुटि को जोड़ती है। फिर यह उस teeप्रोग्राम के माध्यम से पाइप करता है जो अपने मानक इनपुट को अपने मानक आउटपुट (जैसे cat) और फ़ाइल में भी भेजेगा । तो यह दो धाराओं (त्रुटि और आउटपुट) को जोड़ती है, फिर टर्मिनल और फ़ाइल को आउटपुट करता है।

लब्बोलुआब यह है कि पहला भेजता है stderr/ stdoutफ़ाइल के लिए, जबकि दूसरा इसे फ़ाइल और मानक आउटपुट दोनों में भेजता है (जो कि संभवतः टर्मिनल है जब तक आप किसी अन्य निर्माण के अंदर नहीं होते हैं जो मानक आउटपुट को पुनर्निर्देशित करता है)।

मैं उस अंतिम संभावना का उल्लेख करता हूं क्योंकि आपके पास सामान हो सकता है:

(echo hello | tee xyzzy.txt) >plugh.txt

जहां टर्मिनल पर कुछ भी समाप्त नहीं होता है।


13
-1 आपके पास वाक्यविन्यास अधिकार है, लेकिन शब्दार्थ नहीं। रन cat /doesnotexist 2>&1 >output.txt- आप देखेंगे cat: /doesnotexist: No such file or directoryकि टर्मिनल को प्रदर्शित किया गया है और output.txt एक खाली फाइल है। पूर्वता और बंद होने का क्रम चल रहा है: 2>&1( वर्तमान fd1 से dd2 fd2), फिर >output.txt(आउटपुट में td1 को रीडायरेक्ट करें। कुछ और नहीं बदलते हुए)। जो कारण 2>&1 |अलग है वह पूर्वता के क्रम के कारण है: |पहले >
Arcege

5
यह उत्तर मूलत: हर लिहाज से गलत है । नीचे दिए गए कई उत्तर बेहतर हैं, लेकिन मुझे लगता है कि कुसलानंद द्वारा यह एक सबसे स्पष्ट है।
माइकल होमर

2
@ user14408: क्या आपको कभी यूनिक्स और लिनक्स पर एक खाता बनाना चाहिए और इस उत्तर पर दावा करना चाहिए , कृपया टिप्पणियों को संबोधित करने के बाद मेरे संपादकीय नोट को हटाने के लिए स्वतंत्र महसूस करें।
अपमानजनक

8

पहला कार्य दूसरा कार्य करेगा:

बाद

2>&1 > output.log 

STDERR में पुराने STDOUT को बचाया (कॉपी किया) जाएगा और फिर STDOUT को फाइल में रीडायरेक्ट किया जाएगा।

तो, stdout फ़ाइल में जाएगा और Stderr कंसोल पर जाएगा।

और में

 2>&1 | tee output.log

दोनों धाराओं को टी पर पुनर्निर्देशित किया जाएगा। टी अपने स्टडआउट (आपके मामले में कंसोल) और फ़ाइल ( output.log) में किसी भी इनपुट की नकल करेगा ।

और पहले का दूसरा रूप है:

    > output.log  2>&1

यह STDOUT और STDERR दोनों को फ़ाइल में रीडायरेक्ट करेगा।


4

पूर्व आउटपुट केवल फ़ाइल के लिए। दूसरा फ़ाइल और स्क्रीन पर दोनों आउटपुट देता है ।


4

इसका कारण 2>&1 | teeएक लॉग फ़ाइल में stdout और stderr दोनों को कैप्चर करना और एक ही समय में स्क्रीन पर देखने में सक्षम होना है। यह भी किया जा सकता है >output.txt 2>&1 & tail -f, लेकिन आपको पता नहीं चलेगा कि पृष्ठभूमि वाली कमांड कब समाप्त हुई - क्या यह प्रोग्राम समाप्त हो गया है या यह बिना आउटपुट के चल रहा है। 2>&1 | teeप्रोग्रामर के लिए एक आम मुहावरा था।


क्या आपके कहने का मतलब यह है कि 2> और 1> file.txt उदाहरण के लिए file.txt के लिए stdout और stderr दोनों को कैप्चर नहीं करेगा?
प्रेरित

0

आइए पहले कुछ नमूना कोड देखें:

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

परिणामों की तुलना करें:
./helloerror
+ फ़ाइल: कोई संदेश नहीं; कंसोल: संदेश 1,2,3;

./helloerror >error.txt
+ फ़ाइल: संदेश 1,2; सांत्वना: संदेश 3;

./helloerror 2>&1 >error.txt
+ फ़ाइल: संदेश 1,2; सांत्वना: संदेश 3;
+ as ./helloerror> error.txt

./helloerror >error.txt 2>&1
+ फ़ाइल: संदेश 3,1,2; सांत्वना: कोई संदेश नहीं;
+ ध्यान दें क्रम 3 पहले है, फिर 1, फिर 2

./helloerror | tee error.txt 2>&1
+ फ़ाइल: संदेश 1,2; कंसोल: संदेश 3,1,2;
+ ध्यान दें क्रम 3 पहले है, फिर 1, फिर 2

./helloerror 2>&1 | tee error.txt
+ फ़ाइल: संदेश 3,1,2; कंसोल: संदेश 3,1,2;

उपयोग करने के लिए:
./helloerror >error.txt 2>&1
-> यदि कोई फ़ाइल में सभी (stdout + stderr) संदेश चाहता है, लेकिन कंसोल पर नहीं है

./helloerror 2>&1 | tee error.txt
-> अगर कोई फ़ाइल में सभी (stdout + stderr) संदेश चाहता है और कंसोल पर मुद्रित होता है


-1

यहां यूनिक्स आउटपुट स्ट्रीम का सारांश दिया गया है: http://www.devcodenote.com/2015/04/unix-output-st.html

पोस्ट से एक स्निपेट:

3 मानक आउटपुट स्ट्रीम हैं:

STDIN - Standard Input - Writes from an input device to the program
STDOUT - Standard Output - Writes program output to screen unless specified otherwise.
STDERR - Standard Error Output - Writes error messages. Also printed to the screen unless specified otherwise.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.