2009-08-01 13 views

उत्तर

31

तकनीकी रूप से इसे डुप्लिकेट, या प्रतियां, stdout stdout पर बोलते हुए।

आमतौर पर आपको इसे निष्पादित करने की आवश्यकता नहीं होती है। फ़ाइल डिस्क्रिप्टर के साथ निष्पादन का एक और सामान्य उपयोग यह इंगित करना है कि आप एक अप्रयुक्त फ़ाइल वर्णनकर्ता को फ़ाइल असाइन करना चाहते हैं, उदा।

exec 35< my_input

BTW मत भूलना कि घोषणा-पत्र के अनुक्रम जब एक फाइल करने के लिए पाइप महत्वपूर्ण है, इसलिए

ls > mydirlist 2>&1 

क्योंकि यह फ़ाइल mydirlist करने के लिए दोनों stdout और stderr निर्देशन काम करेंगे, जबकि आदेश

ls 2>&1 > mydirlist 

, mydirlist दायर करने के लिए केवल stdout निर्देशन, और stderr नहीं है, क्योंकि stderr stdou से पहले stdout की एक प्रति बनाया गया था टी को mydirlist पर रीडायरेक्ट किया गया था।

संपादित करें: यह तरीका है कि खोल बाएं से दाएं स्कैनिंग काम करता है। तो दूसरे व्यक्ति को "mydirlist को stdout भेजें" कहने से पहले "stdout पर stderr" कहने के रूप में पढ़ें। इसके बाद पहले व्यक्ति को "mydirlist फ़ाइल को stdout भेजें" कहने से पहले यह कहें कि "उस stdout पर डुप्लिकेट stderr मैंने सेट अप किया है"। मुझे पता है। यह पूरी तरह सहज नहीं है!

+0

क्षमा करें, मुझे यह समझ में नहीं आता है। तो stderr को stdout को निर्देशित करना और फिर किसी फ़ाइल में stdout को निर्देशित करना काम नहीं करता है, लेकिन एक फ़ाइल में stdout निर्देशित करता है और फिर stderr stdout कार्यों को निर्देशित करता है? ऐसा लगता है कि यह विपरीत होना चाहिए। –

+1

@bjarkef, ऊपर संपादित देखें देखें। –

+0

वास्तव में बहुत काउंटर सहज ज्ञान युक्त। मैं बिल्कुल ऐसा करने की कोशिश कर रहा हूं क्योंकि मुझे नहीं पता कि कितनी बार और आश्चर्य हुआ कि यह कभी काम क्यों नहीं करता है। बहुत बहुत धन्यवाद। –

10

यह करने के लिए बाहर

2 मानक मानक त्रुटि बांध stderr है और 1 stdout है। जब आप कोई प्रोग्राम चलाते हैं, तो आपको सामान्य आउटपुट stdout में मिल जाएगा, लेकिन किसी भी त्रुटि या चेतावनियां आमतौर पर stderr पर जाती हैं। यदि आप उदाहरण के लिए सभी आउटपुट को फ़ाइल में पाइप करना चाहते हैं, तो पहले 2>&1 के साथ stdout के साथ stderr को गठबंधन करना उपयोगी है।

+1

बिना आदेश के निष्पादन निष्पादन एक छिपी हुई विशेषता नहीं है (यह मूल दस्तावेज़ में है) लेकिन फिर भी मेरे लिए नया है। मजेदार बात .. –

+0

यह 'stdout करने के लिए पाइप stderr' नहीं है। आप कह सकते हैं कि यह stdout से stderr संबंध है 'या यह stderr और stdout सहयोगी'। डेटा पाइप हो जाता है, फाइल डिस्क्रिप्टर नहीं करते हैं। –

+0

धन्यवाद विलियम, मैंने इसे 'ties' में बदल दिया है –

2

@ सीएमए की तरह, यह stdout पर stderr डालता है। कारण आप इस व्यवहार को चाहते हैं कि grep या किसी अन्य उपयोगिता का उपयोग आउटपुट को कैप्चर करने के लिए करें जो केवल stderr पर दिखाई देता है। या आप बाद में प्रसंस्करण के लिए फ़ाइल में stderr सहित सभी आउटपुट को सहेजना चाहते हैं।

22

"2> & 1" पर देखे गए बेहतर लेखों में से एक Bash One-Liners Explained, Part III: All about redirections है।

लेकिन इस प्रश्न पर वर्तमान उत्तर देने में असफल रहा है कि आप इसे सादे "निष्पादन" के बाद क्यों करना चाहते हैं। चूंकि निष्पादन कमांड के लिए बैश मैन पेज बताता है: "यदि कमांड निर्दिष्ट नहीं है, तो मौजूदा शेल में कोई भी रीडायरेक्शन प्रभावी होता है"।

मैं out-and-err.py कहा जाता है एक सरल स्क्रिप्ट कि stdout के लिए उत्पादन की एक पंक्ति लिखते हैं, और एक और लाइन लिखा stderr करने के लिए:

#!/usr/bin/python 
import sys 
sys.stdout.write('this is stdout.\n') 
sys.stderr.write('this is stderr.\n') 

और फिर मैं एक खोल स्क्रिप्ट में बाहर बुलाया कि लिपटे -और-गलती।एक "कार्यकारी 2> & 1" के साथ श:

#!/bin/bash 
exec 2>&1 
./out-and-err 

अगर मैं सिर्फ अजगर स्क्रिप्ट चलाने, stdout और stderr अलग कर रहे हैं:

$ ./out-and-err.pl 1> out 2> err 
$ cat out 
this is stdout. 
$ cat err 
the is stderr. 

लेकिन अगर मैं खोल स्क्रिप्ट चलाने के लिए, आप देख सकते हैं कि कार्यकारी के बाद सब कुछ के लिए stderr का ख्याल रखता है: अपने रैपिंग खोल स्क्रिप्ट सिर्फ एक अजगर आदेश तुलना में बहुत अधिक है, और आप stdout में संयुक्त सभी उत्पादन की जरूरत है

$ ./out-and-err.sh 1> out 2> err 
$ cat out 
this is stdout. 
this is stderr. 
$ cat err 
$ 

हैं, "exec 2> & 1" करने से आपके लिए यह आसान हो जाएगा।

+1

भयानक उत्तर, अन्य यह समझाते हुए विफल रहे कि पुनर्निर्देशन पूरे खोल (या लिपि) में मान्य है! और उदाहरण स्पष्टीकरण है। – caesarsol

0

exec 2>&1 का एक बहुत ही उपयोगी अनुप्रयोग है जो मैंने पार किया है जब आप stderr और stdout को अर्धविराम से अलग कई आदेशों के लिए मर्ज करना चाहते हैं। मेरे विशिष्ट उदाहरण हुआ जब मैं PHP में popen लिए एक से अधिक आदेश भेज रही थी और मैं देखना चाहता त्रुटियों interleaved की तरह आप अगर आप एक खोल प्रॉम्प्ट पर आदेशों टाइप किया देखना होगा चाहता था:

$ echo hi ; yikes ; echo there 
hi 
-bash: yikes: command not found 
there 
$ 

निम्नलिखित मर्ज नहीं होता stderr और stdout पिछले echo के लिए (जो व्यर्थ है क्योंकि yikes त्रुटि होती है) को छोड़कर:

+०१२३५१६४१०६१:

echo hi ; yikes ; echo there 2>&1 

मैं मर्ज किए गए उत्पादन "मुश्किल तरीके से" के रूप में इस प्राप्त कर सकते हैं

echo hi 2>&1; yikes 2>&1; echo there 2>&1 

यह एक बहुत क्लीनर और त्रुटियों की संभावना कम लग रहा है अगर आप exec का उपयोग करें:

exec 2>&1 ; echo hi; echo yikes; echo there 

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

संबंधित मुद्दे