bash खोल में, "2> और 1" का क्या अर्थ है?




shell unix (12)

2 कंसोल मानक त्रुटि है।

1 कंसोल मानक आउटपुट है।

यह मानक यूनिक्स है, विंडोज भी पॉज़िक्स का पालन करता है। जैसे आप दौड़ते हैं

perl test.pl 2>&1

मानक त्रुटि मानक आउटपुट पर रीडायरेक्ट की जाती है, ताकि आप दोनों आउटपुट एक साथ देख सकें।

perl test.pl > debug.log 2>&1

निष्पादन के बाद, आप debug.log में त्रुटियों समेत सभी आउटपुट देख सकते हैं।

perl test.pl 1>out.log 2>err.log

फिर मानक आउटपुट out.log, और err.log में मानक त्रुटि के लिए जाता है।

मैं आपको इन्हें समझने की कोशिश करने का सुझाव देता हूं।

यूनिक्स शैल में, यदि मैं आगे बढ़ने के लिए stdout स्ट्रीम में stderr और stdout को जोड़ना चाहता हूं, तो मैं अपने आदेश के अंत में निम्नलिखित जोड़ सकता हूं:

2>&1

इसलिए, अगर मैं g ++ से आउटपुट पर "हेड" का उपयोग करना चाहता हूं, तो मैं ऐसा कुछ कर सकता हूं:

g++ lots_of_errors 2>&1 | head

तो मैं केवल पहली कुछ त्रुटियों को देख सकता हूं।

मुझे हमेशा याद रखने में परेशानी होती है, और मुझे लगातार इसे देखना होगा, और यह मुख्य रूप से इसलिए है क्योंकि मैं इस विशेष चाल के वाक्यविन्यास को पूरी तरह से समझ नहीं पा रहा हूं। क्या कोई इसे तोड़ सकता है और चरित्र के चरित्र को "2> और 1" का अर्थ बता सकता है?


लोग, हमेशा पुनर्निर्देशन लक्ष्य के वर्तमान स्थान के बारे में पक्सडीब्लो का संकेत याद रखें ... यह महत्वपूर्ण है।

2>&1 ऑपरेटर के लिए मेरा व्यक्तिगत निमोनिक यह है:

  • 'and' या 'add' अर्थ के रूप में सोचें (चरित्र एक एम्पर है - और , है ना?)
  • तो यह हो जाता है: ' 2 (stderr) को रीडायरेक्ट करें जहां 1 (stdout) पहले से / वर्तमान में है और दोनों धाराएं जोड़ें

अन्य अक्सर इस्तेमाल किए जाने वाले पुनर्निर्देशन के लिए एक ही निमोनिक काम, 1>&2 :

  • सोचें & अर्थ दें and add ... (आपको एम्परसैंड के बारे में विचार मिलता है, हाँ?)
  • तो यह हो जाता है: ' 1 (stdout) को पुनर्निर्देशित करें जहां 2 (stderr) पहले से / वर्तमान में है और दोनों धाराएं जोड़ें

और हमेशा याद रखें: आपको दाएं से बाएं (बाएं से दाएं) तक, 'अंत से' पुनर्निर्देशन की श्रृंखलाएं पढ़नी होंगी।


एक प्रोग्रामर के दृष्टिकोण से, इसका मतलब यह है कि:

dup2(1, 2);

मैन पेज देखें।

समझना कि 2>&1 एक प्रतिलिपि भी बताती है कि क्यों ...

command >file 2>&1

... जैसा नहीं है ...

command 2>&1 >file

पहला file को दोनों स्ट्रीम भेज देगा, जबकि दूसरा stdout त्रुटियों को भेज देगा, और file में सामान्य आउटपुट भेजेगा।


इनपुट के लिए 0, stdout के लिए 1 और stderr के लिए 2।

एक युक्ति : somecmd >1.txt 2>&1 सही है, जबकि कुछ somecmd 2>&1 >1.txt कोई प्रभाव नहीं है!


2>&1 एक पॉज़िक्स खोल निर्माण है। यहां एक ब्रेकडाउन है, टोकन द्वारा टोकन:

2 : " मानक त्रुटि " आउटपुट फ़ाइल वर्णनकर्ता।

>& : एक आउटपुट फ़ाइल डिस्क्रिप्टर ऑपरेटर डुप्लिकेट करें ( आउटपुट रीडायरेक्शन ऑपरेटर का एक संस्करण > )। दिया गया [x]>&[y] , x द्वारा निर्दिष्ट फ़ाइल डिस्क्रिप्टर आउटपुट फ़ाइल डिस्क्रिप्टर y की एक प्रति बनने के लिए बनाया गया है।

1 " मानक आउटपुट " आउटपुट फ़ाइल डिस्क्रिप्टर।

अभिव्यक्ति 2>&1 प्रतियां फाइल डिस्क्रिप्टर 1 को स्थान 2 , इसलिए निष्पादन वातावरण में 2 ("मानक त्रुटि") पर लिखे गए किसी भी आउटपुट को मूल रूप से 1 ("मानक आउटपुट") द्वारा वर्णित उसी फ़ाइल पर जाता है।

आगे की व्याख्या:

फ़ाइल डिस्क्रिप्टर : "प्रति-प्रक्रिया अद्वितीय, गैर-ऋणात्मक पूर्णांक फ़ाइल पहुंच के उद्देश्य के लिए एक खुली फ़ाइल की पहचान करने के लिए उपयोग किया जाता है।"

मानक आउटपुट / त्रुटि : खोल प्रलेखन के Redirection खंड में निम्न नोट का संदर्भ लें:

खुली फ़ाइलें शून्य से शुरू होने वाली दशमलव संख्याओं द्वारा दर्शायी जाती हैं। सबसे बड़ा संभव मूल्य कार्यान्वयन-परिभाषित है; हालांकि, आवेदन द्वारा उपयोग के लिए सभी कार्यान्वयन कम से कम 0 से 9 का समर्थन करेंगे। इन नंबरों को "फाइल डिस्क्रिप्टर" कहा जाता है। मान 0, 1, और 2 में विशेष अर्थ और पारंपरिक उपयोग हैं और कुछ पुनर्निर्देशन संचालन द्वारा निहित हैं; उन्हें क्रमशः मानक इनपुट, मानक आउटपुट और मानक त्रुटि के रूप में जाना जाता है। कार्यक्रम आमतौर पर मानक इनपुट से अपना इनपुट लेते हैं, और मानक आउटपुट पर आउटपुट लिखते हैं। त्रुटि संदेश आमतौर पर मानक त्रुटि पर लिखा जाता है। फ़ाइल डिस्क्रिप्टर नंबर को नामित करने के लिए पुनर्निर्देशन ऑपरेटरों को एक या अधिक अंकों (बिना हस्तक्षेप करने वाले वर्णों के साथ) से पहले किया जा सकता है।


अपने प्रश्न का उत्तर देने के लिए: इसमें कोई त्रुटि आउटपुट होता है (आमतौर पर stderr को भेजा जाता है) और इसे मानक आउटपुट (stdout) में लिखता है।

यह उपयोगी है, उदाहरण के लिए 'अधिक' जब आपको सभी आउटपुट के लिए पेजिंग की आवश्यकता होती है। Stderr में मुद्रण उपयोग जानकारी जैसे कुछ कार्यक्रम।

आपको याद रखने में मदद करने के लिए

  • 1 = मानक आउटपुट (जहां प्रोग्राम सामान्य आउटपुट प्रिंट करते हैं)
  • 2 = मानक त्रुटि (जहां प्रोग्राम त्रुटियों को प्रिंट करते हैं)

"2> और 1" बस stderr को भेजे गए सबकुछ को इंगित करता है, इसके बजाय stdout करने के लिए।

मैं इस पोस्ट को त्रुटि पुनर्निर्देशन पर पढ़ने की भी सिफारिश करता हूं जहां यह विषय पूर्ण विवरण में शामिल है।


यह निर्माण मानक आउटपुट ( stdout ) को मानक आउटपुट ( stdout ) के वर्तमान स्थान पर भेजता है - यह मुद्रा समस्या अन्य उत्तरों द्वारा उपेक्षित की गई प्रतीत होती है।

आप इस विधि का उपयोग कर किसी भी आउटपुट हैंडल को दूसरे पर रीडायरेक्ट कर सकते हैं लेकिन प्रोसेसिंग के लिए इसे एक ही स्ट्रीम में stdout और stderr स्ट्रीम को चैनल करने के लिए अक्सर उपयोग किया जाता है।

कुछ उदाहरण निम्न हैं:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

ध्यान दें कि आखिरी वाला stderr को outfile2 निर्देशित नहीं करेगा - यह उस पर रीडायरेक्ट करता है जब तर्क का सामना करना पड़ा था ( outfile1 ) और फिर stdout को outfile2 रीडायरेक्ट outfile2

यह कुछ सुंदर परिष्कृत चालबाजी की अनुमति देता है।


संख्या फाइल डिस्क्रिप्टर (एफडी) का संदर्भ लें।

  • शून्य stdin
  • एक stdout
  • दो stderr

2>&1 एफडी 2 से 1 को रीडायरेक्ट करता है।

यदि प्रोग्राम उनका उपयोग करता है तो यह किसी भी फ़ाइल डिस्क्रिप्टर के लिए काम करता है।

यदि आप उन्हें भूल जाते हैं तो आप /usr/include/unistd.h देख सकते हैं:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

उस ने कहा कि मैंने सी टूल्स लिखे हैं जो कस्टम लॉगिंग के लिए गैर-मानक फ़ाइल डिस्क्रिप्टर का उपयोग करते हैं ताकि आप इसे तब तक नहीं देख सकें जब तक कि आप इसे किसी फ़ाइल या किसी चीज़ पर रीडायरेक्ट नहीं करते।


इनपुट रीडायरेक्टिंग

इनपुट का पुनर्निर्देशन फ़ाइल का वर्णन करता है जिसका नाम फ़ाइल डिस्क्रिप्टर एन पर पढ़ने के लिए शब्द के विस्तार से खोला जाता है, या मानक इनपुट (फ़ाइल डिस्क्रिप्टर 0) यदि एन निर्दिष्ट नहीं है।

इनपुट रीडायरेक्ट करने के लिए सामान्य प्रारूप है:

      [n]<word

आउटपुट रीडायरेक्टिंग

आउटपुट का पुनर्निर्देशन फ़ाइल का वर्णन करता है जिसका नाम फ़ाइल वर्णक एन पर लिखने के लिए शब्द के विस्तार से खोला जाता है, या मानक आउटपुट (फ़ाइल डिस्क्रिप्टर 1) यदि एन निर्दिष्ट नहीं है। अगर फ़ाइल मौजूद नहीं है तो यह बनाया गया है; यदि यह अस्तित्व में है तो इसे शून्य आकार में छोटा कर दिया गया है।

आउटपुट रीडायरेक्ट करने के लिए सामान्य प्रारूप है:

      [n]>word

फ़ाइल डिस्क्रिप्टर चल रहा है

मूविंग फाइल डिस्क्रिप्टर रीडायरेक्शन ऑपरेटर

      [n]<&digit-

फाइल डिस्क्रिप्टर अंक को डिस्क्रिप्टर एन, या मानक इनपुट (फ़ाइल डिस्क्रिप्टर 0) फ़ाइल करने के लिए चलाता है यदि n निर्दिष्ट नहीं है। एन को डुप्लीकेट होने के बाद अंक बंद कर दिया गया है।

इसी प्रकार, पुनर्निर्देशन ऑपरेटर

      [n]>&digit-

फाइल डिस्क्रिप्टर अंक को डिस्क्रिप्टर एन, या मानक आउटपुट (फ़ाइल डिस्क्रिप्टर 1) फ़ाइल में ले जाता है यदि n निर्दिष्ट नहीं है।

रेफरी:

man bash
प्रकार /^REDIRECT redirection अनुभाग का पता लगाने के लिए /^REDIRECT , और जानें ..

यहां एक ऑनलाइन संस्करण:
http://www.gnu.org/software/bash/manual/bashref.html#Redirections

पुनश्च:

बहुत समय, man लिनक्स सीखने के लिए शक्तिशाली उपकरण था


फ़ाइल डिस्क्रिप्टर 1 मानक आउटपुट (stdout) है।
फ़ाइल डिस्क्रिप्टर 2 मानक त्रुटि (stderr) है।

इस निर्माण को याद रखने का एक तरीका यहां है (हालांकि यह पूरी तरह से सटीक नहीं है): पहले, 2>1 stderr को stdout पर रीडायरेक्ट करने के लिए एक अच्छा तरीका दिख सकता है। हालांकि, इसे वास्तव में "नामित फ़ाइल में stderr को रीडायरेक्ट" के रूप में व्याख्या किया जाएगा। & इंगित करता है कि एक फ़ाइल डिस्क्रिप्टर क्या है और फ़ाइल नाम नहीं है। तो निर्माण बन जाता है: 2>&1


पुनर्निर्देशन के बारे में कुछ चालें

इसके बारे में कुछ वाक्यविन्यास विशिष्टता में महत्वपूर्ण व्यवहार हो सकते हैं। पुनर्निर्देशन, STDERR , STDOUT और तर्कों के आदेश के बारे में कुछ छोटे नमूने हैं।

1 - ओवरराइटिंग या संलग्न करना?

सिम्बोले > मतलब पुनर्निर्देशन

  • > मतलब पूरी तरह से पूर्ण फ़ाइल के रूप में भेजें , यदि मौजूद हो तो ओवरराइटिंग लक्ष्य (बाद में # 3 पर noclobber bash सुविधा देखें)।
  • >> यदि मौजूद है तो लक्ष्य को जोड़ने के अलावा अतिरिक्त भेजना है।

कोई भी मामला, फ़ाइल तब बनाई जाएगी जब वे मौजूद न हों।

2 - खोल कमांड लाइन ऑर्डर निर्भर है !!

इसका परीक्षण करने के लिए, हमें एक साधारण कमांड की आवश्यकता है जो दोनों आउटपुट पर कुछ भेज देगा :

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(उम्मीद है कि आपके पास निश्चित रूप से नाम /tnt निर्देशिका नहीं है;)। खैर, हमारे पास है !!

तो देखते हैं:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

कंसोल पर अंतिम कमांड लाइन डंप STDERR , ऐसा लगता है कि यह अपेक्षित व्यवहार नहीं है ... लेकिन ...

यदि आप एक आउटपुट के बारे में कुछ पोस्ट फ़िल्टर करना चाहते हैं, तो दूसरा या दोनों:

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

ध्यान दें कि इस अनुच्छेद में अंतिम कमांड लाइन पिछले पैरागैफ़ की तरह ही है, जहां मैंने लिखा है कि अपेक्षित व्यवहार नहीं है (इसलिए, यह एक अपेक्षित व्यवहार भी हो सकता है)।

वैसे दोनों दोनों आउटपुट पर अलग-अलग ऑपरेशन करने के लिए, पुनर्निर्देशन के बारे में कुछ छोटी सी चीजें हैं:

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

नोटा: &9 ) 9>&2 कारण &9 वर्णनकर्ता स्वचालित रूप से घटित होंगे।

परिशिष्ट: नोटा! bash ( >4.0 ) के नए संस्करण के साथ इस तरह की चीजों को करने के लिए एक नई सुविधा और अधिक सेक्सी वाक्यविन्यास है:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

और इस तरह के एक कैस्केडिंग आउटपुट स्वरूपण के लिए finaly:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

परिशिष्ट: नोटा! दोनों नए तरीकों से वही नया वाक्यविन्यास:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

जहां STDOUT एक विशिष्ट फ़िल्टर के माध्यम से जाता है, STDERR दूसरे को और आखिरकार दोनों आउटपुट विलय हो जाते हैं जो तीसरे कमांड फ़िल्टर के माध्यम से जाते हैं।

3 - noclobber विकल्प और >| बारे में एक शब्द वाक्य - विन्यास

यह ओवरराइटिंग के बारे में है:

set -o noclobber निर्देश किसी भी मौजूदा फ़ाइल को ओवरराइट करने के लिए set -o noclobber निर्देश, >| वाक्यविन्यास आपको इस सीमा से गुज़रने देता है:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

फ़ाइल हर बार ओवरराइट की जाती है, ठीक है अब:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

के माध्यम से गुजरें >| :

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

इस विकल्प को अनसेट करना और / या पहले से सेट होने पर पूछताछ करना।

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - अंतिम चाल और अधिक ...

दिए गए आदेश से दोनों आउटपुट को पुनर्निर्देशित करने के लिए, हम देखते हैं कि एक सही वाक्यविन्यास हो सकता है:

$ ls -ld /tmp /tnt >/dev/null 2>&1

इस विशेष मामले के लिए, एक शॉर्टकट वाक्यविन्यास है: &> ... या >&

$ ls -ld /tmp /tnt &>/dev/null 

$ ls -ld /tmp /tnt >&/dev/null 

नोटा: यदि 2>&1 मौजूद है, 1>&2 एक सही वाक्यविन्यास भी है:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4 बी- अब, मैं आपको इसके बारे में सोचने दूँगा:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4 सी- यदि आप अधिक जानकारी में रुचि रखते हैं

आप मारकर ठीक मैनुअल पढ़ सकते हैं:

man -Len -Pless\ +/^REDIRECTION bash

एक bash कंसोल में ;-)


यह सिर्फ stdout या टर्मिनल में त्रुटि को मापने की तरह है। अर्थात । cmd $ cmd 2 कमांड नहीं है> फ़ाइल नाम बिल्ली फ़ाइल नाम कमांड नहीं मिला है

फ़ाइल में भेजा गया त्रुटि उस 2> और 1 त्रुटि टर्मिनल को भेजी गई





redirect