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


2281

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

2>&1

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

g++ lots_of_errors 2>&1 | head

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

मुझे इसे याद रखने में हमेशा परेशानी होती है, और मुझे लगातार इसे देखते रहना पड़ता है, और यह मुख्य रूप से है क्योंकि मैं इस विशेष ट्रिक के सिंटैक्स को पूरी तरह से नहीं समझता।

क्या कोई इसे तोड़ सकता है और चरित्र द्वारा चरित्र की व्याख्या कर सकता 2>&1 है?


50
@dbr मुझे नहीं लगता कि यह सिर्फ बकवास है - मेरा मानना ​​है कि यह एक बोर्न शेल चीज़ है; इसलिए श, बश, ksh, राख, पानी का छींटा, आदि
बंदूकें

8
यह पुनर्निर्देशन पैराग्राफ का हिस्सा है जिसमें POSIX- संगत शैल या शॉर्ट के लिए POSIX शेल का वर्णन किया गया है। ksh उदाहरण के लिए एक POSIX शेल है। देखें: pubs.opengroup.org/onlinepubs/009695399/utilities/…
jim mcnamara

12
यह निर्माण विंडोज पर भी काम करता है।
वडज़िम

2
यह आम तौर पर बेहतर कर रहा है 2>&1की तुलना में 2> / dev / बातिल ;-)
एफ HAURI

11
मैंने सोचा कि मैं उल्लेख करें कि |& के लिए आशुलिपि है 2>&1 |आप zsh उपयोग कर रहे हैं। मैं यह नहीं बोल सकता कि क्या यह अन्य बोर्न-जैसे गोले पर लागू होता है या यदि यह केवल एक zsh सुविधा है।
Chrixian

जवाबों:


2553

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

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


280
लेकिन तब यह नहीं होना चाहिए &2>&1?
डोकसपार

319
@Dominik: नहीं, &केवल पुनर्निर्देशन के संदर्भ में "फाइल डिस्क्रिप्टर" का अर्थ समझा जाता है। लेखन के command &2>&रूप में पार्स किया जाता है command &और 2>&1, अर्थात " commandपृष्ठभूमि में चलाते हैं , फिर कमांड को चलाते हैं 2और इसके स्टडआउट को रीडायरेक्ट करते हैं"।
एडम रोसेनफील्ड

15
उन्होंने इस तरह के सामान को क्यों चुना? बस उत्सुक।
कॉममाटॉस्ट

81
लेकिन आप '& 1' नाम की फ़ाइल में स्ट्रीडर को कैसे रीडायरेक्ट करेंगे?
मार्टीन फिक्समैन 17

120
@Martin:2>'&1'

631
echo test > afile.txt

रीडायरेक्ट करने के लिए stdout afile.txt। यह ऐसा ही है

echo test 1> afile.txt

Stderr को पुनर्निर्देशित करने के लिए, आप निम्न कार्य करते हैं:

echo test 2> afile.txt

>& किसी अन्य फ़ाइल डिस्क्रिप्टर के लिए एक स्ट्रीम को पुनर्निर्देशित करने के लिए सिंटैक्स है - 0 स्टड है, 1 स्टडआउट है, और 2 स्टडर है।

आप stdout को stderr पर रीडायरेक्ट कर सकते हैं:

echo test 1>&2 # or echo test >&2

या ठीक इसके विपरीत:

echo test 2>&1

इसलिए, संक्षेप में ... 2>एक (अनिर्दिष्ट) फ़ाइल पर &1stderr को पुनर्निर्देशित करता है, पुनर्निर्देशित stderr को stoutout में जोड़ता है।


5
क्या इससे आपको कोई मतलब है java ... 2&1 >> data.log, मैंने देखा, मेरे एक सहयोगी ने ऐसा किया था?
थांग फाम

5
@ हैरी जो दिखने में या तो एक खोल की तरह होती है, जो बैश नहीं है, या एक टाइपो है .. cmd 2>&1 >> somefile.logएक फाइल में stdout / stderr को जोड़ देगा - यह मूल रूप से ऊपर जैसा है, >> fileअपेंड के साथ
dbr

73
@ ddr cmd 2>&1 >>fileफ़ाइल में stderr को पुनर्निर्देशित नहीं करता है, लेकिन cmd >> file 2>&1करता है। आदेश मायने रखता है। पहले मामले में, स्टैडर को शेल के स्टडआउट पर भेज दिया जाता है (संभवतः एक ट्टी यदि कमांड को अंतःक्रियात्मक रूप से दर्ज किया जाता है), और फिर स्टडआउट को फ़ाइल में निर्देशित किया जाता है। दूसरे मामले में, stdout को फ़ाइल में निर्देशित किया जाता है, और फिर उसी स्थान पर stderr को निर्देशित किया जाता है।
विलियम पर्ससेल

2
मुझे ऊपर का उत्तर पसंद है, लेकिन यह एक स्पर्श स्पष्ट हो सकता है। "2> और 1" stdout के लक्ष्य के लिए stderr को पुनर्निर्देशित करता है। इसलिए यदि आपके पास "ls -l >> directoryContents 2> & 1" जैसा कुछ है, तो परिणाम एक फाइल होगी, जिसका नाम DirectoryContents होगा, इसमें काम करने वाली डायरेक्टरी की सामग्री होगी। यदि निष्पादन में कोई त्रुटियां हैं: त्रुटि संदेश भी निर्देशिका निर्देशिका फ़ाइल में जोड़े जाएंगे, जैसा कि वे होते हैं।
मैक्स वेस्ट

1
है 0(or 1,2)>&0(or 1,2)उत्पादन को नियंत्रित करने के लिए एक विकल्प की तरह? के echo test >test.log 2>&1रूप में ही है echo test 2>&1 >test.log?
सिमिन जी

318

पुनर्निर्देशन के बारे में कुछ टोटके

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

1 - ओवरराइटिंग या एपेंडिंग?

प्रतीक का >अर्थ है पुनर्निर्देशन

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

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

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

परिशिष्ट: नोटा! के नए संस्करण के साथ( >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

और अंत में ऐसी कैस्केडिंग आउटपुट स्वरूपण के लिए:

$ ((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 करने के लिए बैश करने का निर्देश देते समय , सिंटैक्स आपको इस सीमा से गुजरने देता है:>|

$ 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

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

$ 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/

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

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

man -Len -Pless\ +/^REDIRECTION bash

में कंसोल ;-)


5
आगे पढ़े: अगर आपको यह पसंद आया है, तो आप यह जान सकते हैं
F. Hauri


130

मुझे पुनर्निर्देशन पर यह शानदार पोस्ट मिली: सभी पुनर्निर्देशन के बारे में

किसी फ़ाइल में मानक आउटपुट और मानक त्रुटि दोनों को पुनर्निर्देशित करें

$ कमांड &> फ़ाइल

यह वन-लाइनर &>कमांड से फाइल तक आउटपुट स्ट्रीम - स्टडआउट और स्टडर - दोनों को पुनर्निर्देशित करने के लिए ऑपरेटर का उपयोग करता है । यह बैश का शॉर्टकट है जो दोनों धाराओं को एक ही गंतव्य पर शीघ्र पुनर्निर्देशित करता है।

बैश के बाद दोनों धाराओं को पुनर्निर्देशित करने के बाद फाइल डिस्क्रिप्टर तालिका इस तरह दिखती है:

यहां छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं, दोनों stdout और stderr अब इंगित करते हैं file। तो stdout और stderr को लिखा गया कुछ भी लिखा जाता है file

दोनों धाराओं को एक ही गंतव्य पर पुनर्निर्देशित करने के कई तरीके हैं। आप प्रत्येक स्ट्रीम को एक के बाद एक रीडायरेक्ट कर सकते हैं:

$ कमांड> फ़ाइल 2> और 1

यह एक फ़ाइल में दोनों धाराओं को पुनर्निर्देशित करने का एक बहुत अधिक सामान्य तरीका है। पहले stdout को फ़ाइल में रीडायरेक्ट किया जाता है, और फिर stdout के समान stderr को डुप्लिकेट किया जाता है। तो दोनों धाराएँ इंगित करती हैं file

जब बैश कई पुनर्निर्देशन देखता है तो यह उन्हें बाएं से दाएं संसाधित करता है। आइए चरणों के माध्यम से देखें और देखें कि ऐसा कैसे होता है। किसी भी कमांड को चलाने से पहले, बैश की फाइल डिस्क्रिप्टर टेबल इस तरह दिखती है:

यहां छवि विवरण दर्ज करें

अब बैश पहले रीडायरेक्शन> फाइल को प्रोसेस करता है। हमने इसे पहले देखा है और यह फ़ाइल के लिए महत्वपूर्ण बिंदु बनाता है:

यहां छवि विवरण दर्ज करें

अगला बैश दूसरा पुनर्निर्देशन 2> और 1 देखता है। हमने इस पुनर्निर्देशन को पहले नहीं देखा है। यह एक फ़ाइल डिस्क्रिप्टर 1 की डुप्लिकेट फ़ाइल की एक प्रति की नकल करता है और हमें मिलता है:

यहां छवि विवरण दर्ज करें

दोनों धाराओं को फाइल करने के लिए पुनर्निर्देशित किया गया है।

हालाँकि यहाँ सावधान रहें! लिख रहे हैं

कमांड> फाइल 2> और 1

लेखन के समान नहीं है:

$ कमांड 2> और 1> फ़ाइल

बैश में मामलों को पुनर्निर्देशित करने का क्रम! यह कमांड केवल मानक आउटपुट को फाइल में रीडायरेक्ट करता है। Stderr अभी भी टर्मिनल पर प्रिंट होगा। यह समझने के लिए कि ऐसा क्यों होता है, आइए फिर से कदमों से गुजरें। इसलिए कमांड चलाने से पहले, फाइल डिस्क्रिप्टर टेबल इस तरह दिखती है:

यहां छवि विवरण दर्ज करें

अब बैश दाएं से बाएं पुनर्निर्देशन की प्रक्रिया करता है। यह पहली बार 2> और 1 देखता है इसलिए यह stdr को stdout डुप्लिकेट करता है। फ़ाइल डिस्क्रिप्टर तालिका बन जाती है:

यहां छवि विवरण दर्ज करें

अब बैश दूसरा रीडायरेक्ट देखता है >file, और यह फ़ाइल के लिए stdout रीडायरेक्ट करता है:

यहां छवि विवरण दर्ज करें

क्या आप देखते हैं कि यहां क्या होता है? Stdout अब फ़ाइल करने के लिए इंगित करता है, लेकिन stderr अभी भी टर्मिनल को इंगित करता है! सब कुछ है कि stderr को लिखा अभी भी स्क्रीन के लिए बाहर मुद्रित हो जाता है! इसलिए, पुनर्निर्देश के आदेश के साथ बहुत सावधान रहें!

यह भी ध्यान दें कि बैश में, लेखन

$ कमांड &> फ़ाइल

बिल्कुल वैसा ही है:

$ कमांड> और फ़ाइल


3
अंतिम दो अलग हैं यदि "कमांड" एक संख्या में समाप्त होती है, तो उस के लिए वैकल्पिक फ़ाइल डिस्क्रिप्टर के रूप में लिया जाता है>&
MM

बहुत अच्छी ड्राइंग और स्पष्टीकरण! क्या आप बता सकते हैं कि वास्तव में "डुप्लिकेट" का क्या मतलब है? आपने उल्लेख किया, "यह एक [2> और 1] फ़ाइल डिस्क्रिप्टर 2 की डुप्लिकेट फ़ाइल डिस्क्रिप्टर 1 की एक प्रति है"। ऐसा लगता है कि stderout stdout को डुप्लिकेट हो जाता है। लेकिन अगर यह मामला है, तो क्या मुझे भी गलत तरीके से देखना चाहिए /dev/tty0?
HCSF

87

संख्या फ़ाइल डिस्क्रिप्टर (fd) को संदर्भित करती है।

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

2>&1 पुनर्निर्देशन fd 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.  */

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


58

यह मानक मानक आउटपुट stderrके वर्तमान स्थान पर मानक त्रुटि स्ट्रीम ( ) भेजता है 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- यह क्या करने के लिए इसे पुनर्निर्देश stdoutथा जब तर्क का सामना करना पड़ा था ( outfile1) और उसके बाद पुनर्निर्देश stdoutकरने के लिए outfile2

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


5
हालाँकि यह अंतिम उदाहरण बहुत स्पष्ट होगा: foo> outfile2 2> outfile1
माइकल क्रैमर

3
क्लीयर, हाँ, लेकिन यह पुनर्निर्देशन की "स्थिति" नहीं दिखाएगा। उदाहरण से वंचित है क्योंकि यह आमतौर पर एक पंक्ति में ऐसा करने के लिए उपयोगी नहीं है - विधि वास्तव में उपयोगी हो जाती है जब विभिन्न पार्टियां पुनर्निर्देशन के विभिन्न हिस्सों के लिए जिम्मेदार होती हैं। उदाहरण के लिए, जब कोई स्क्रिप्ट एक बिट पुनर्निर्देशन करती है और आप इसे दूसरे बिट के साथ चलाते हैं।
paxdiablo

5
मुझे बस एहसास हुआ कि अंतिम उदाहरण भी लंबे समय से भ्रम की स्थिति को हल करता है जो मुझे इस बारे में था कि इस some_program 2>&1 > /dev/nullतरह से काम नहीं करता है some_program > /dev/null 2>&1:।
Snapfractalpop

पिछले उदाहरण के बारे में आपकी टिप्पणी सोने में इसके अक्षरों के लायक है :-) मैंने कभी नहीं सोचा था कि ये पुनर्निर्देशन तर्क स्थितिगत हैं ... मुझे लगता है कि यह जानना बहुत महत्वपूर्ण है।
नेल्स-ओ-मैट

20

2>&1एक POSIX शेल निर्माण है। यहाँ एक टूटन है, टोकन द्वारा टोकन:


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

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

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

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


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

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

मानक आउटपुट / त्रुटि : शेल दस्तावेज़ के पुनर्निर्देशन अनुभाग में निम्नलिखित नोट का संदर्भ लें :

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


19

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

1 कंसोल स्टैंडर्ड आउटपुट है।

यह मानक यूनिक्स है, और विंडोज भी POSIX का अनुसरण करता है।

जैसे जब आप दौड़ते हैं

perl test.pl 2>&1

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

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

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

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

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

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


दूसरा नमूना गलत है: जैसा कि आदेश पूर्वता STDERR को STDOUT पर पुनर्निर्देशित किया गया है , केवल डिफॉल्ट STDOUT को debug.log ( STDERR नहीं ) लिखा जाएगा , मेरा उत्तर देखें (पैराग्राफ # 2)! यह सुनिश्चित करने के लिए कि दोनों को एक ही फाइल पर पुनर्निर्देशित किया जाए, आपको निर्देश पुनर्निर्देशित करना होगा:perl test.pl > debug.log 2>&1
F. Hauri

16

आपके प्रश्न का उत्तर देने के लिए: यह किसी भी त्रुटि आउटपुट (सामान्य रूप से stderr पर भेजा गया) लेता है और इसे मानक आउटपुट (stdout) पर लिखता है।

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

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

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

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

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


11

एक प्रोग्रामर के दृष्टिकोण से, इसका ठीक यही अर्थ है:

dup2(1, 2);

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

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

command >file 2>&1

... के रूप में ही नहीं है ...

command 2>&1 >file

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


8

मुझे यह बहुत मददगार लगा अगर आप एक शुरुआती हैं तो इसे पढ़ें

अद्यतन:
लिनक्स या यूनिक्स प्रणाली में दो स्थानों के कार्यक्रम आउटपुट भेजते हैं: मानक आउटपुट (स्टडआउट) और मानक त्रुटि (स्टडर) । आप इन आउटपुट को किसी भी फ़ाइल पर पुनर्निर्देशित कर सकते हैं।

जैसे यदि आप ऐसा करते हैं तो

ls -a > output.txt

कुछ भी नहीं होगा कंसोल में प्रिंट किया जाएगा सभी आउटपुट (स्टडआउट) को आउटपुट फ़ाइल पर रीडायरेक्ट किया जाता है।

और अगर आप किसी भी फाइल के कंटेंट को प्रिंट करने की कोशिश करते हैं जो बाहर नहीं निकलती है तो इसका मतलब है कि आउटपुट में कोई त्रुटि होगी जैसे कि यदि आप test.txt प्रिंट करते हैं तो वर्तमान निर्देशिका में मौजूद नहीं है

cat test.txt > error.txt

आउटपुट होगा

cat: test.txt :No such file or directory

लेकिन error.txt फाइल खाली हो जाएगी क्योंकि हम stdout को एक फाइल में रीडायरेक्ट नहीं कर रहे हैं।

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

तो अब अगर आप ऐसा करते हैं तो

ls -a 1> output.txtइसका मतलब है कि आप Standard.txt (stdout) को output.txt पर भेज रहे हैं।

और यदि आप ऐसा करते हैं, तो

cat test.txt 2> error.txtइसका मतलब है कि आप error.txt को Standard Error (stderr) भेज रहे हैं।

&1का उपयोग फाइल डिस्क्रिप्टर 1 (स्टडआउट) के मूल्य को संदर्भित करने के लिए किया जाता है।

अब इस बिंदु का 2>&1मतलब है कि "उसी स्थान पर स्टैडर को पुनर्निर्देशित करें जहां हम स्टडआउट को रीडायरेक्ट कर रहे हैं"

अब आप ऐसा कर सकते हैं

cat maybefile.txt > output.txt 2>&1

दोनों मानक उत्पादन (stdout) और मानक त्रुटि (stderr) output.txt पर पुनर्निर्देशित किया जाएगा।

इशारा करने के लिए ओन्ड्रेज के। का धन्यवाद


1
लिंक केवल उत्तर समस्याग्रस्त हैं। लिंक बेकार जवाब देने के लिए विचलित हो सकता है। आपको हमेशा उत्तर में ही पर्याप्त विवरण शामिल करना चाहिए।
ओन्ड्रेज के।

7

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

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

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

अन्य बार-बार उपयोग किए जाने वाले पुनर्निर्देशन के लिए भी यही मेमोनिक काम करता है 1>&2:

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

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


7

पुनर्निर्देशित इनपुट

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

पुनर्निर्देशित इनपुट का सामान्य प्रारूप है:

[n]<word

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

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

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

[n]>word

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

पुनर्निर्देशन ऑपरेटर,

[n]<&digit-

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

इसी तरह, पुनर्निर्देशन ऑपरेटर

[n]>&digit-

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

संदर्भ:

man bash

अनुभाग /^REDIRECTका पता लगाने के लिए टाइप करें redirection, और अधिक जानें ...

एक ऑनलाइन संस्करण यहां है: 3.6 पुनर्निर्देशन

पुनश्च:

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


6

बशर्ते /fooआपके सिस्टम पर मौजूद न हो और /tmp

$ ls -l /tmp /foo

की सामग्री को प्रिंट करेगा /tmpऔर के लिए एक त्रुटि संदेश प्रिंट करेगा/foo

$ ls -l /tmp /foo > /dev/null

की सामग्री को भेज देंगे /tmpकरने के लिए /dev/nullऔर के लिए एक त्रुटि संदेश मुद्रित/foo

$ ls -l /tmp /foo 1> /dev/null

ठीक वैसा ही करेंगे (नोट 1 )

$ ls -l /tmp /foo 2> /dev/null

की सामग्री प्रिंट करेगा /tmpऔर त्रुटि संदेश भेजेगा/dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

दोनों प्रविष्टि और साथ ही त्रुटि संदेश को भेजेगा /dev/null

$ ls -l /tmp /foo > /dev/null 2> &1

आशुलिपि है


5

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

यह cmdएक आदेश नहीं है:

$cmd 2>filename
cat filename

command not found

त्रुटि इस तरह फ़ाइल में भेजी जाती है:

2>&1

मानक त्रुटि टर्मिनल को भेजी जाती है।


1

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

एक टिप : somecmd >1.txt 2>&1सही है, जबकि बिना किसी प्रभाव के somecmd 2>&1 >1.txtपूरी तरह से गलत है!


1

unix_commands 2>&1

इसका उपयोग टर्मिनल में त्रुटियों को प्रिंट करने के लिए किया जाता है।

निम्नलिखित प्रक्रिया को दिखाता है

  • जब त्रुटियां उत्पन्न होती हैं, तो उन्हें मानक त्रुटि मेमोरी एड्रेस &2"बफर" में लिखा जाता है , जिसमें से मानक त्रुटि स्ट्रीम 2संदर्भ होता है।
  • जब आउटपुट का उत्पादन किया जाता है, तो इसे मानक आउटपुट मेमोरी एड्रेस &1"बफर" में लिखा जाता है , जिसमें से मानक आउटपुट स्ट्रीम 1संदर्भ होता है।

इसलिए unix_commandsमानक त्रुटि स्ट्रीम लें 2, और >स्ट्रीम (त्रुटियों की) को मानक आउटपुट मेमोरी पते पर पुनर्निर्देशित करें &1, ताकि उन्हें टर्मिनल पर मुद्रित किया जा सके।

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