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


988

बैश में, कॉलिंग fooस्टैडआउट पर उस कमांड से किसी भी आउटपुट को प्रदर्शित करेगा।

कॉलिंग foo > outputउस कमांड से किसी भी आउटपुट को निर्दिष्ट फ़ाइल में पुनर्निर्देशित करेगी (इस मामले में 'आउटपुट')।

क्या किसी फ़ाइल पर आउटपुट पुनर्निर्देशित करने का एक तरीका है और क्या यह स्टडआउट पर प्रदर्शित होता है?


3
यदि कोई व्यक्ति फ़ाइल को त्रुटि आउटपुट कैप्चर करने के लिए यहाँ समाप्त होता है, तो एक नज़र डालें - unix.stackexchange.com/questions/132511/…
मर्फी

2
शब्दावली पर एक नोट: जब आप निष्पादित foo > outputडेटा है stdout और stdout में लिखा है नाम की फ़ाइल output। यही है, फ़ाइल को लिखना stdout को लिखना है। आप पूछ रहे हैं कि क्या स्टडआउट और टर्मिनल तक दोनों को लिखना संभव है।
विलियम पर्सेल

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

जवाबों:


1377

आपको जो आदेश चाहिए उसका नाम है tee:

foo | tee output.file

उदाहरण के लिए, यदि आप केवल स्टडआउट की परवाह करते हैं:

ls -a | tee output.file

यदि आप stderr को शामिल करना चाहते हैं, तो करें:

program [arguments...] 2>&1 | tee outfile

2>&1चैनल 2 (stderr / standard error) को चैनल 1 (stdout / standard output) में पुनर्निर्देशित करता है, जैसे कि दोनों को stdout लिखा जाता है। यह teeकमांड के रूप में दिए गए आउटपुट फाइल को भी निर्देशित करता है ।

इसके अलावा, यदि आप लॉग फ़ाइल में संलग्न करना चाहते हैं, तो निम्नानुसार उपयोग करें tee -a:

program [arguments...] 2>&1 | tee -a outfile

173
अगर ओपी चाहता है कि "सभी आउटपुट" को पुनर्निर्देशित किया जाए, तो आपको stderr को भी हथियाना होगा: "ls -lR / 2> & 1 - tee output.file"
जेम्स ब्रैडी

45
@evanmcdonnal उत्तर गलत नहीं है, यह सिर्फ विशिष्ट पर्याप्त नहीं हो सकता है, या आपकी आवश्यकताओं के आधार पर पूरा हो सकता है। निश्चित रूप से ऐसी स्थितियाँ हैं, जहाँ आप नहीं चाहते कि किसी फ़ाइल में सहेजे जा रहे आउटपुट के हिस्से के रूप में स्टैडर हो। जब मैंने 5 साल पहले इसका उत्तर दिया तो मैंने मान लिया कि ओपी केवल स्टडआउट चाहते थे, क्योंकि उन्होंने पोस्ट के विषय में स्टैडआउट का उल्लेख किया था।
Zoredache

3
आह क्षमा करें, मैं थोड़ा भ्रमित हो सकता था। जब मैंने इसे आज़माया तो मुझे बस कोई आउटपुट नहीं मिला, शायद यह सब stderr को जा रहा था।
evanmcdonnal

38
कंटेंट को अपेंड करने के बजाय, उसे -ateeoutput.filels -lR / | tee -a output.file
आगे बढ़ाने के

16
यदि आप $?बाद में उपयोग कर रहे हैं तो यह स्थिति कोड लौटा देगा tee, जो कि शायद आप नहीं चाहते हैं। इसके बजाय, आप उपयोग कर सकते हैं ${PIPESTATUS[0]}
लागाट

501
$ program [arguments...] 2>&1 | tee outfile

2>&1स्टंपर और स्टडआउट स्ट्रीम को डंप करता है। tee outfileइसे जो स्ट्रीम मिलती है वह इसे स्क्रीन पर और फाइल "आउटफिट" में लिख देता है।

यह शायद वही है जो ज्यादातर लोग ढूंढ रहे हैं। संभावित स्थिति कुछ कार्यक्रम या स्क्रिप्ट लंबे समय तक कड़ी मेहनत कर रही है और बहुत सारे उत्पादन का उत्पादन कर रही है। उपयोगकर्ता इसे समय-समय पर प्रगति के लिए जाँचना चाहता है, लेकिन फ़ाइल में लिखा आउटपुट भी चाहता है।

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

यह भी बुरा है अगर कार्यक्रम प्रगति की रिपोर्ट करने के लिए केवल कुछ ही मिनटों में 1 या 2 लाइनों का उत्पादन करता है। ऐसे मामले में, यदि आउटपुट प्रोग्राम द्वारा फ्लश नहीं किया गया था, तो उपयोगकर्ता को घंटों तक स्क्रीन पर कोई आउटपुट दिखाई नहीं देगा, क्योंकि इसमें से कोई भी घंटे के लिए पाइप के माध्यम से धक्का नहीं देगा।

अद्यतन: कार्यक्रम unbuffer, expectपैकेज का हिस्सा , बफरिंग समस्या को हल करेगा। यह स्क्रीन और फ़ाइल को लिखने के लिए स्टडआउट और स्टॉडर का कारण बनेगा और संयुक्त और पुनर्निर्देशित होने पर उन्हें सिंक में रखेगा tee। उदाहरण के लिए:

$ unbuffer program [arguments...] 2>&1 | tee outfile

7
किसी को भी ऑक्स के लिए एक 'अनबफर' का पता है?
जॉन मे

7
यदि आप अनबफ़र का उपयोग नहीं कर सकते हैं, तो GNU कोरुटिल्स में stdbuff नामक एक उपकरण शामिल है, जिसका उपयोग आउटपुट बफरिंग को रोकने के लिए किया जा सकता है$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
पीटर

1
यदि आप OS X का उपयोग कर रहे हैं, तो अधिकांश मामलों में अनबफ़र का उपयोग करना थोड़ा आसान है, हालांकि यदि आप कमांड को चलाने के लिए सिग्नल पास नहीं करना चाहते हैं। मेरी टिप्पणी उन उपयोगकर्ताओं के लिए अधिक लक्षित थी जो लिनक्स पर हैं, जहां कोरुटिल्स डिफ़ॉल्ट रूप से सबसे अधिक संभावना है। @ ईथन, इस उत्तर को देखें यदि आप stdbuf सिंटैक्स के बारे में भ्रमित हैं: stackoverflow.com/a/25548995/942781
पीटर

3
ध्यान दें कि pythonएक अंतर्निहित विकल्प है -uजो आउटपुट को अनबफ़र करता है।
fabian789

1
एमएल मॉडल के प्रशिक्षण के लिए पूर्ण जीवन शैली, जहां मैं अतिरिक्त कोड के बिना लॉग इन करना चाहता हूं, लेकिन यह चलाने में लगने वाले घंटों / दिनों में आउटपुट भी देखता है, धन्यवाद!
रोकोको

126

एक और तरीका है जो मेरे लिए काम करता है,

<command> |& tee  <outputFile>

जैसा कि गन्न बैश मैनुअल में दिखाया गया है

उदाहरण:

ls |& tee files.txt

यदि '| &' का उपयोग किया जाता है, कमांड 1 की मानक त्रुटि , इसके मानक आउटपुट के अलावा , पाइप के माध्यम से कमांड 2 के मानक इनपुट से जुड़ी है; यह 2> और 1 के लिए आशुलिपि है | मानक आउटपुट के लिए मानक त्रुटि का यह अंतर्निहित पुनर्निर्देशन कमांड द्वारा निर्दिष्ट किसी भी पुनर्निर्देशन के बाद किया जाता है।

अधिक जानकारी के लिए, पुनर्निर्देशन देखें


10
यदि आप $?बाद में उपयोग कर रहे हैं तो यह स्थिति कोड लौटा देगा tee, जो कि शायद आप नहीं चाहते हैं। इसके बजाय, आप उपयोग कर सकते हैं ${PIPESTATUS[0]}
लागाट

1
यह विधि रंगीन कंसोल आउटपुट, किसी भी विचार को छोड़ देती है?
shakram02

कोशिश करें: अनबफ़र ls -l --color = ऑटो | tee files.txt
लुसियानो एंड्रेस मार्टिनी

17

आप मुख्य रूप से Zoredache समाधान का उपयोग कर सकते हैं , लेकिन यदि आप आउटपुट फ़ाइल को अधिलेखित नहीं करना चाहते हैं , तो आपको -a विकल्प के साथ टी लिखना चाहिए:

ls -lR / | tee -a output.file

11

कुछ जोड़ने के लिए ...

पैकेज अनबफर में फेडोरा और रिडैट यूनिक्स रिलीज के तहत कुछ पैकेज के साथ समर्थन मुद्दे हैं।

परेशानियों को दूर करना

निम्नलिखित मेरे लिए काम किया

bash myscript.sh 2>&1 | tee output.log

धन्यवाद ScDF और मैथ्यू आपके इनपुट ने मेरा बहुत समय बचाया।



3

इस उपयोग-मामले के बाद से बोनस उत्तर मुझे यहां लाया गया:

मामले में जहां आपको कुछ अन्य उपयोगकर्ता के रूप में ऐसा करने की आवश्यकता है

echo "some output" | sudo -u some_user tee /some/path/some_file

ध्यान दें कि इको आपके जैसा होगा और फ़ाइल राइट "some_user" के रूप में होगा, जो काम नहीं करेगा यदि आप इको को "some_user" के रूप में चलाएं और आउटपुट को >> "some_file" के साथ रीडायरेक्ट करें क्योंकि फ़ाइल रीडायरेक्ट होगी। जैसे तुम।

संकेत: टी-ऑफ फ्लैग के साथ एपेंड को भी सपोर्ट करता है, यदि आपको फाइल में एक लाइन को बदलने की जरूरत है तो दूसरे यूजर के रूप में आप वांछित यूजर के रूप में सेड को निष्पादित कर सकते हैं।


2

< command > |& tee filename # इससे एक फाइल "फ़ाइल नाम" कमांड स्टेटस के रूप में कंटेंट के रूप में बनेगा, यदि कोई फाइल पहले से मौजूद है तो वह मौजूद सामग्री को हटा देगा और कमांड स्टेटस लिख देगा।

< command > | tee >> filename # यह फ़ाइल में स्थिति को जोड़ देगा लेकिन यह standard_output (स्क्रीन) पर कमांड की स्थिति को प्रिंट नहीं करता है।

मैं स्क्रीन पर "इको" का उपयोग करके कुछ प्रिंट करना चाहता हूं और उस इको डेटा को एक फाइल में संलग्न करना चाहता हूं

echo "hi there, Have to print this on screen and append to a file" 

1

आप अपनी स्क्रिप्ट की शुरुआत में ऐसा कुछ करके अपनी पूरी स्क्रिप्ट के लिए ऐसा कर सकते हैं:

#!/usr/bin/env bash

test x$1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee mylogfile ; exit $? ; }

# do whaetever you want

इस रीडायरेक्ट दोनों stderr और कहा जाता फाइल करने के लिए stdout आउटपुट mylogfile और सब कुछ stdout में चला जाता है चलो एक ही समय में

इसका उपयोग कुछ मूर्खतापूर्ण तरकीबों में किया जाता है:

  • execपुनर्निर्देशन के लिए कमांड के बिना उपयोग ,
  • teeआउटपुट डुप्लिकेट करने के लिए उपयोग करें,
  • वांछित पुनर्निर्देशन के साथ स्क्रिप्ट को पुनरारंभ करें,
  • यह निर्दिष्ट करने के लिए कि स्क्रिप्ट को फिर से शुरू किया गया है (कोई मूल पैरामीटर आपके मूल कार्य द्वारा उपयोग नहीं किया जा सकता है) विशेष फर्स्ट पैरामीटर ( विशेष बैश नोटेशन NULद्वारा निर्दिष्ट एक साधारण अक्षर $'string') का उपयोग करें।
  • pipefailविकल्प का उपयोग करके स्क्रिप्ट को पुनरारंभ करते समय मूल निकास स्थिति को संरक्षित करने का प्रयास करें ।

बदसूरत लेकिन कुछ स्थितियों में मेरे लिए उपयोगी।


-13

टी इसके लिए एकदम सही है, लेकिन यह काम भी करेगा

ls -lr / > output | cat output

10
यह एक त्रुटि है यदि आउटपुट पहले से मौजूद नहीं है और यह वह नहीं करता है जो आप चाहते हैं यदि यह करता है, तो कुल मिलाकर यह निरर्थक है। शायद आपका मतलब था "?" इसके बजाय "|" ?
रॉबर्ट गैंबल

6
यहां तक ​​कि अगर आपने एक का उपयोग किया है ;, तो धीमी गति से कमांड के दौरान आउटपुट में बहुत देरी होगी।
ब्रैड कोच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.