कैसे बैश के साथ एक फ़ाइल में stdout और stderr दोनों को पुनर्निर्देशित करें और अपग्रेड करें?


1533

बैश में छंटनी की गई फ़ाइल के लिए stdout को पुनर्निर्देशित करने के लिए, मैं उपयोग करना जानता हूं:

cmd > file.txt

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

cmd >> file.txt

एक छंटनी की गई फ़ाइल में stdout और stderr दोनों को पुनर्निर्देशित करने के लिए, मैं उपयोग करना जानता हूं:

cmd &> file.txt

मैं एक फ़ाइल में संलग्न दोनों stdout और stderr को कैसे पुनर्निर्देशित करूं ? cmd &>> file.txtमेरे लिए काम नहीं किया।


37
मैं यह नोट करना चाहूंगा कि & संगठन एक बैश (और अन्य) विशिष्ट कोड है और पोर्टेबल नहीं है। पोर्टेबल जाने का तरीका (
आगामी

जवाबों:


1996
cmd >>file.txt 2>&1

बैश बाएं से दाएं पर पुनर्निर्देशित करता है:

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

33
बहुत अच्छा काम करता है! लेकिन क्या इसका कोई मतलब है या क्या मुझे इसका इलाज परमाणु बैश निर्माण की तरह करना चाहिए?
फ्लाईबवायर

181
यह सरल पुनर्निर्देशन है, पुनर्निर्देशन कथनों का मूल्यांकन हमेशा की तरह बाएं से दाएं किया जाता है। >> फ़ाइल: लाल। फ़ाइल (परिशिष्ट मोड) (1 >> फ़ाइल के लिए छोटा) 2> और 1: लाल। STDERR "जहां stdout जाता है" ध्यान दें कि व्याख्या "STDERR को STDOUT में पुनर्निर्देशित करना" गलत है।
बोनसाई

31
यह कहते हैं "आउटपुट जोड़ें (stdout, फ़ाइल डिस्क्रिप्टर 1) file.txt पर और उसी स्थान पर fder1 के लिए stderr (फाइल डिस्क्रिप्टर 2) भेजें"।
अगली सूचना तक रोक दिया गया।

2
@Bonsai लेकिन क्या होगा यदि मुझे STDERR को किसी अन्य फ़ाइल में अनुप्रेषित करने की आवश्यकता है, लेकिन संलग्न? क्या यह संभव है?
अरोड

41
यदि आप ऐसा करते हैं, तो आपको cmd >>file1 2>>file2वह हासिल करना चाहिए जो आप चाहते हैं।
वुडरो डगलस

367

ऐसा करने के दो तरीके हैं, जो आपके बैश संस्करण पर निर्भर करता है।

क्लासिक और पोर्टेबल ( बैश पूर्व -4 ) तरीका है:

cmd >> outfile 2>&1

बैश 4 से शुरू होने वाला एक गैर-लाभकारी तरीका है

cmd &>> outfile

(अनुरूप &> outfile)

अच्छी कोडिंग शैली के लिए, आपको चाहिए

  • तय करें कि पोर्टेबिलिटी एक चिंता है (फिर क्लासिक तरीके का उपयोग करें)
  • तय करें कि क्या बैश प्री -4 में भी पोर्टेबिलिटी एक चिंता है (फिर क्लासिक तरीके का उपयोग करें)
  • कोई फर्क नहीं पड़ता कि आप किस वाक्यविन्यास का उपयोग करते हैं, इसे उसी स्क्रिप्ट (भ्रम) के भीतर न बदलें!

यदि आपकी स्क्रिप्ट पहले से ही #!/bin/sh(यदि कोई इरादा है या नहीं) के साथ शुरू होती है , तो बैश 4 समाधान, और सामान्य रूप से किसी भी बैश-विशिष्ट कोड में जाने का तरीका नहीं है।

यह भी याद रखें कि बैश 4 &>>केवल छोटा सिंटैक्स है - यह किसी भी नई कार्यक्षमता या उस जैसी किसी भी चीज़ को पेश नहीं करता है।

सिंटैक्स यहाँ वर्णित (अन्य पुनर्निर्देशन सिंटैक्स के पास) है: http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_andor_error_output


8
मैं पसंद करता हूं & >> जैसा कि यह &> और >> के अनुरूप है। 'फ़ाइल में आउटपुट भेजना, इस फ़ाइल में आउटपुट जोड़ना' की तुलना में इस ऐप में 'एपेंड आउटपुट और एरर पढ़ना' आसान है। ध्यान दें, जबकि लिनक्स में आम तौर पर बैश का एक मौजूदा संस्करण होता है, OS X, लेखन के समय, फिर भी
होमबॉव

मुझे यह अधिक पसंद है क्योंकि यह प्रति पंक्ति छोटी और केवल चिमटी वाली जगहें हैं, इसलिए उदाहरण के लिए zsh "और >>" से क्या बना सकता है?
फिलिप

यह भी नोट करना महत्वपूर्ण है, कि एक क्रॉन जॉब में, आपको प्री -4 सिंटैक्स का उपयोग करना होगा, भले ही आपके सिस्टम में बैश 4 हो
हाइपरनोट

5
@zsero क्रोन बश का उपयोग बिल्कुल नहीं करता है ... यह उपयोग करता है sh। आप फ़ाइल SHELL=/bin/bashको प्रस्तुत करके डिफ़ॉल्ट शेल को बदल सकते हैं crontab -e
रे फॉस

89

बैश में आप अपने रीडायरेक्ट को स्पष्ट रूप से अलग-अलग फाइलों में निर्दिष्ट कर सकते हैं:

cmd >log.out 2>log_error.out

लागू होगा:

cmd >>log.out 2>>log_error.out

6
अपने पहले विकल्प का उपयोग करके एक ही फ़ाइल में दो धाराओं को पुनर्निर्देशित करने से पहले वाले को दूसरे के "शीर्ष पर" लिखने का कारण होगा, कुछ या सभी सामग्रियों को अधिलेखित करना। का प्रयोग करें cmd >> log.out 2> log.out बजाय।
ओरैस्टिस पी।

3
उस पकड़ने के लिए धन्यवाद; आप सही कह रहे हैं, एक दूसरे को उलझा देगा। हालाँकि, आपका आदेश या तो काम नहीं करता है। मुझे लगता है कि उसी फ़ाइल को लिखने का एकमात्र तरीका जैसा कि पहले दिया गया है cmd >log.out 2>&1। मैं पहला उदाहरण निकालने के लिए अपना उत्तर संपादित कर रहा हूं।
एरोन आर।

65

बैश 4 में (साथ ही साथ ZSH 4.3.11):

cmd &>>outfile

सिर्फ बॉक्स से बाहर


2
@all: यह एक अच्छा जवाब है, क्योंकि यह बैश के साथ काम करता है और संक्षिप्त है, इसलिए मैंने यह सुनिश्चित करने के लिए संपादन किया है कि यह स्पष्ट रूप से बैश का उल्लेख करता है।
मिकमेकाना

10
@mikemaccana: TheBonsai का जवाब 2009 के बाद से 4 समाधान दिखाता है
jfs

52

यह ठीक काम करना चाहिए:

your_command 2>&1 | tee -a file.txt

यह फाइल में सभी लॉग्स को स्टोर करेगा। साथ ही उन्हें टर्मिनल पर डंप करेगा।


यदि आप टर्मिनल में आउटपुट देखना चाहते हैं तो यह सही उत्तर है। हालांकि, यह मूल रूप से पूछा गया सवाल नहीं था।
मिको रानाल्टेनन

25

इसे इस्तेमाल करे

You_command 1>output.log  2>&1

आपका & x.file का उपयोग bash4 में काम करता है। उसके लिए खेद है : (

यहाँ कुछ अतिरिक्त सुझाव दिए गए हैं।

0, 1, 2 ... 9 बैश में फाइल डिस्क्रिप्टर हैं।

0 के लिए खड़ा है stdin, 1 के लिए खड़ा है stdout, 2 के लिए खड़ा है stderror। 3 ~ 9 किसी अन्य अस्थायी उपयोग के लिए अतिरिक्त है।

किसी भी फ़ाइल डिस्क्रिप्टर को ऑपरेटर >या >>परिशिष्ट का उपयोग करके अन्य फ़ाइल डिस्क्रिप्टर या फ़ाइल पर पुनर्निर्देशित किया जा सकता है ।

उपयोग: < file_descriptor > > < फ़ाइल नाम | & file_descriptor >

कृपया http://www.tldp.org/LDP/abs/html/io-redirection.html पर देखें


आपका उदाहरण ओपी द्वारा पूछे गए से कुछ अलग करेगा: यह You_commandstdout के stderr और You_commandफ़ाइल के stdout को पुनर्निर्देशित करेगा output.log। इसके अतिरिक्त यह फ़ाइल में संलग्न नहीं होगा लेकिन यह इसे अधिलेखित कर देगा।
पाबौक

सही: फ़ाइल विवरणक कोई भी मान हो सकता है जो अन्य सभी फ़ाइलों के लिए 3 से अधिक हो।
इताची

5
आपका उत्तर सबसे आम आउटपुट पुनर्निर्देशन त्रुटि दिखाता है: STDERR को उस स्थान पर पुनर्निर्देशित करना जहाँ STDOUT वर्तमान में इंगित कर रहा है और उसके बाद ही फ़ाइल को STDOUT पर पुनर्निर्देशित करना है। यह STDERR को उसी फ़ाइल पर पुनर्निर्देशित नहीं करेगा। पुनर्निर्देश मामलों का आदेश।
12

1
इसका मतलब यह है, मुझे पहले STDERROR को STDOUT में रीडायरेक्ट करना चाहिए, फिर किसी फाइल में STDOUT को रीडायरेक्ट करना चाहिए। 1 > output.log 2>&1
क्विंटस। झोउ

1
@ क्विंटस.ज़ोउ यूप। आपका संस्करण गलत तरीके से, और उसी समय फ़ाइल के लिए रीडायरेक्ट करता है।
एलेक्स यारोशेविच

11

मुझे आश्चर्य है कि लगभग दस वर्षों में, किसी ने भी इस दृष्टिकोण को पोस्ट नहीं किया है:

यदि बैश के पुराने संस्करणों का उपयोग करना &>>उपलब्ध नहीं है, तो आप यह भी कर सकते हैं:

(cmd 2>&1) >> file.txt

यह एक उपधारा को जन्म देता है, इसलिए यह पारंपरिक दृष्टिकोण से कम कुशल है cmd >> file.txt 2>&1 , और यह फलस्वरूप होगा आदेशों की जरूरत वर्तमान खोल संशोधित करने के लिए काम करते नहीं (जैसे cd, pushd), लेकिन इस दृष्टिकोण मेरे लिए और अधिक प्राकृतिक और समझने लगता है:

  1. Stdout को पुनर्निर्देशित करें।
  2. एक फ़ाइल में जोड़कर नए स्टडआउट को पुनर्निर्देशित करें।

इसके अलावा, कोष्ठक क्रम के किसी भी अस्पष्टता को दूर करते हैं, खासकर यदि आप स्टडआउट और स्टडर को इसके बजाय किसी अन्य कमांड पर पाइप करना चाहते हैं।


यह कार्यान्वयन सिस्टम को चलाने के लिए एक अतिरिक्त प्रक्रिया का कारण बनता है। cmd >> file 2>&1सभी गोले में वाक्य रचना का उपयोग करना और चलाने के लिए एक अतिरिक्त प्रक्रिया की आवश्यकता नहीं है।
मिक्को रैंटलैनेन

@ मायको रैंटलैनेन मैंने पहले ही समझाया कि यह एक उपधारा को पैदा करता है और कम कुशल होता है। इस दृष्टिकोण का मुद्दा यह है कि अगर दक्षता कोई बड़ी बात नहीं है (और ऐसा शायद ही कभी होता है), इस तरह से याद रखना आसान है और गलत होने के लिए कठिन है।
jamesdlin
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.