मैं बैट स्क्रिप्ट में किसी फ़ाइल में कंसोल आउटपुट को कैसे प्रतिध्वनित और प्रेषित करता हूं?


136

मेरे पास एक बैच स्क्रिप्ट है जो किसी कार्य को निष्पादित करती है और आउटपुट को एक पाठ फ़ाइल में भेजती है। क्या कंसोल विंडो पर आउटपुट शो होने का कोई तरीका है?

उदाहरण के लिए:

c:\Windows>dir > windows-dir.txt

क्या dirकंसोल विंडो में डिस्प्ले के आउटपुट के साथ-साथ टेक्स्ट फाइल में डालने का कोई तरीका है ?


यहाँ आपके द्वारा किए गए पुनर्निर्देशन और कुछ उदाहरणों के बारे में बताया गया है। <br> आशा है कि यह मदद करता है :)
emoSTN


कृपया ध्यान दें, @Vadzim, कि 2 फरवरी 2009 को 16:38 पर पूछे गए एक प्रश्न को 28 अप्रैल 2009 को 06:32 पर लगभग तीन महीने बाद पूछे गए एक प्रश्न के डुप्लिकेट के रूप में नहीं समझा जा सकता है।
कंपो

जवाबों:


216

नहीं, आप शुद्ध पुनर्निर्देशन नहीं कर सकते।
लेकिन कुछ ट्रिक्स (जैसे टी.बीएट ) के साथ आप कर सकते हैं।

मैं पुनर्निर्देशन को थोड़ा समझाने की कोशिश करता हूं।

आप दस धाराओं में से किसी एक को > फ़ाइल या <फ़ाइल
के साथ पुनर्निर्देशित करते हैं। यह महत्वहीन है, यदि पुनर्निर्देशन कमांड से पहले या बाद में है, तो ये दोनों लाइनें लगभग समान हैं।

dir > file.txt
> file.txt dir

इस उदाहरण में पुनर्निर्देशन केवल 1> के लिए एक शॉर्टकट है , इसका मतलब धारा 1 (STDOUT) को पुनर्निर्देशित किया जाएगा।
इसलिए आप किसी भी स्ट्रीम को 2> इरेटेक्स जैसे प्रीपेडिंग के साथ रिडायरेक्ट कर सकते हैं। इसे एक लाइन में कई स्ट्रीम रिडायरेक्ट करने की भी अनुमति है।

dir 1> files.txt 2> err.txt 3> nothing.txt

इस उदाहरण में "मानक आउटपुट" files.txt में जाएगा, सभी त्रुटियां इरेटेक्स में होंगी और स्ट्रीम 3 कुछ भी नहीं में जाएगा। (DIR धारा 3 का उपयोग नहीं करता है)।
Stream0 STDIN
स्ट्रीम 1 है STDOUT
Stream2 है STDERR
स्ट्रीम 3-9 का उपयोग नहीं किया जाता है

लेकिन अगर आप एक ही स्ट्रीम को कई बार रीडायरेक्ट करने की कोशिश करते हैं तो क्या होता है?

dir > files.txt > two.txt

"केवल एक ही हो सकता है", और यह हमेशा अंतिम होता है!
तो यह dir> two.txt के बराबर है

ठीक है, एक अतिरिक्त संभावना है, एक धारा को दूसरी धारा में पुनर्निर्देशित करना।

dir 1>files.txt 2>&1 

2> & 1 रीडायरेक्ट स्ट्रीम 2 से स्ट्रीम 1 और 1> files.txt रीडायरेक्ट सभी files.txt पर
आदेश यहाँ महत्वपूर्ण है!

dir ... 1>nul 2>&1
dir ... 2>&1 1>nul

अलग है। पहले एक NUL में सभी (STDOUT और STDERR) को
रीडायरेक्ट करता है , लेकिन दूसरी लाइन NUL और STDERR को "खाली" STDOUT में रीडायरेक्ट करती है।

एक निष्कर्ष के रूप में, यह स्पष्ट है कि ओटवियो डेसियो और एंडोमार्नाक्स के उदाहरण क्यों काम नहीं कर सकते हैं।

command > file >&1
dir > file.txt >&2

दोनों दो बार धारा 1 को पुनर्निर्देशित करने की कोशिश करते हैं, लेकिन "केवल एक ही हो सकता है", और यह हमेशा अंतिम होता है।
तो आप प्राप्त करें

command 1>&1
dir 1>&2

और पहले नमूने में स्ट्रीम 1 से स्ट्रीम 1 तक पुनर्निर्देशन की अनुमति नहीं है (और बहुत उपयोगी नहीं है)।

आशा करता हूँ की ये काम करेगा।


24
तो यह देशी खिड़कियों के खोल के साथ असंभव है
कल्पनाशील

7
@fantastory यह संभव है, debham विंडोज बैच
jeb

97
मुझे विश्वास नहीं हो रहा है कि मैं इस पूरी पोस्ट को पढ़कर यह पता लगा सकता हूँ कि पूरी बात को "नहीं" के रूप में संक्षेप में प्रस्तुत किया जा सकता है।
चार्ल्स मैककेल्वे

1
दूसरे तंत्र के बारे में क्या "संभाल दोहराव"? मैंने प्रयोग किया 3<&2(जीटी के बजाय एलटी पर ध्यान दें), और फिर 3>errors.txt। लेकिन यह बुरी तरह से समाप्त हो गया - बाद के सभी stderr आउटपुट पर कब्जा कर लिया गया errors.txt(वह है - अन्य कमांड से भी!)।
टॉमस गैंडर

आप for /f "delims=" %%v in ('dir') do echo %%v>>file.txtहालांकि उपयोग कर सकते हैं ।
स्क्रिप्टमस्टेरे02

32

बस इस तरह से UNIX टी कमांड ( http://unxutils.sourceforge.net से पाया गया ) के विंडोज संस्करण का उपयोग करें :

mycommand > tee outpu_file.txt

यदि आपको STDERR आउटपुट की भी आवश्यकता है, तो निम्न का उपयोग करें। STDOUT में STDERR निर्गम (प्राथमिक स्ट्रीम) को जोड़ती है।
2>&1

mycommand 2>&1 | tee output_file.txt

3
PowerShell टी वस्तु प्रदान करता है इसी तरह की सुविधा। जाओ-प्रक्रिया | Tee-Object -file c: \ script \ test.txt
केविन Obee

मैंने इसे पॉवरशेल और रेगुलर शेल दोनों में आजमाया। कमांड को कॉल करने के बजाय 1>tee a.txtनाम की एक फ़ाइल पर पुनः निर्देशित करेगा । किसी को भी इस जवाब की पुष्टि कर सकते हैं उनके लिए काम करता है? teetee
माफ़ू

@ मफू मैं इसकी पुष्टि कर सकता हूं।
Cerno

@ मफू ऊपर का जवाब थोड़ा अनिश्चित है। आपको पाइप का उपयोग करना होगा "|" शीर्ष उदाहरण में ">" के बजाय। अजीब बात है, उस मामले में कमांड लाइन पर STDOUT और STDERR आउटपुट का क्रम मिलाया गया था। हालांकि नीचे का उदाहरण मेरे लिए पूरी तरह से काम करता है।
Cerno

इसके अलावा, मेरे लिए सोर्सफोर्ज डाउनलोड टूट गया था। : मैं यहाँ एक वैकल्पिक मेजबान पाया wzw.tum.de/public-html/syring/win32/UnxUtilsDist.html (म्यूनिख विश्वविद्यालय)
Cerno

9

यदि आपको वास्तविक समय में आउटपुट की आवश्यकता नहीं है (जैसे कि कार्यक्रम इसे लिख रहा है) तो आप जोड़ सकते हैं

type windows-dir.txt

उस लाइन के बाद।


या उसी लाइन पर (प्रॉम्प्ट पर उपयोगी) dir > windows-dir.txt & type windows-dir.txt:। यह भी ब्लॉक करने के लिए लागू होता है: ( echo %date% <NL> echo %username% <NL> echo %time% <NL> pause>CON )>test.txt & type test.txt। हालाँकि, यदि आउटपुट वास्तविक समय में आवश्यक है, तो आप इसके लिए टी टूल के विंडोज़ पोर्ट का उपयोग कर सकते हैं ...
mousio

7

मेरे लिए काम करने वाला समाधान था: dir> a.txt | a.txt टाइप करें


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

यह समस्याग्रस्त होगा यदि आप> के बजाय> का उपयोग करें
नीम मेघ

6

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

@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt

विस्तृत विवरण:

FORआदेश एक चर, कई बार संदर्भित किया जा सकता है जिसमें एक आदेश या पाठ के उत्पादन में पार्स करता है।

एक कमांड के लिए, जैसे कि DIR /B, एकल उद्धरण में संलग्न करें जैसा कि नीचे उदाहरण में दिखाया गया है। DIR /Bटेक्स्ट को अपने इच्छित कमांड से बदलें ।

FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT

पाठ प्रदर्शित करने के लिए, दोहरे उद्धरण में पाठ संलग्न करें जैसा कि नीचे उदाहरण में दिखाया गया है।

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT

... और लाइन रैपिंग के साथ ...

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
  ECHO %%I & ECHO %%I>>FILE.TXT
)

यदि आपके पास ऐसा समय है जब आप केवल कंसोल (स्क्रीन) पर आउटपुट चाहते हैं, और अन्य बार केवल फ़ाइल में भेजा जाता है, और अन्य बार दोनों को भेजा जाता है, तो फ़ोर लूप के "डीओ" क्लॉज़ को एक चर का उपयोग करके निर्दिष्ट करें, जैसा कि नीचे दिखाया गया है %TOECHOWHERE%

@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
  FOR %%J IN (TRUE FALSE) DO (
    SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish

:Runit
  REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
  REM above when the FOR loops are evaluating the first item in the list,
  REM "TRUE".  So, the first value of TOSCREEN is "TRUE " (with a trailing
  REM space), the second value is "FALSE" (no trailing or leading space).
  REM Adding the ": =" text after "TOSCREEN" tells the command processor to
  REM remove all spaces from the value in the "TOSCREEN" variable.
  IF "%TOSCREEN: =%"=="TRUE" (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=On screen, and in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
        ) ELSE (
          SET TEXT=On screen, not in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I"
      )
    ) ELSE (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=Not on screen, but in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>>FILE.txt"
        ) ELSE (
          SET TEXT=Not on screen, nor in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>NUL"
      )
  )
  FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof

:Finish
  ECHO Finished [this text to console (screen) only].
  PAUSE

आपको delims=इसके बजाय उपयोग करना चाहिए ।
स्क्रिप्टमस्टेरे02

3
command > file >&1

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

@andynormancx yup सीएमडी से कट और पेस्ट के बजाय टाइप करना भूल गया।
रैंडम डेवलपर

मैं विंडोज़ कमांड प्रॉम्प्ट के तहत काम करने के लिए सिंटैक्स नहीं प्राप्त कर सका और इसके बजाय टाइप कमांड के साथ चला गया।
जेम्सएगर्स

& 2 काम करता है, हालांकि जब मैं इसका परीक्षण करता हूं तो फाइल नहीं बनती है।
जेम्सएगर्स

5
यदि मैं "dir> file.txt> & 2" करता हूं तो file.txt नहीं बनाया जा रहा है। निर्देशिका का आउटपुट कंसोल में गूँज रहा है लेकिन फ़ाइल नहीं बनाई जा रही है। फ़ाइल तब बनाई जाती है जब "> और 2" मौजूद नहीं होता है।
जेम्सएगर्स

2

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

dir 1>> files.txt 2>> err.txt

या

dir 1>> files.txt 2>>&1

2

मेरा विकल्प यह था:

एक सबरूटीन बनाएं जो संदेश में ले जाता है और इसे कंसोल और लॉग फ़ाइल दोनों को भेजने की प्रक्रिया को स्वचालित करता है।

setlocal
set logfile=logfile.log

call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"    

goto :eof

:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b

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


वाह! मुझे वास्तव में पसंद है!! मैंने हालांकि तीन बदलाव किए, मुझे उम्मीद है कि आप उन्हें पसंद करेंगे। 1) मैं setlocal enabledelayedexpansionसिर्फ setlocal 2 के बजाय उपयोग करता हूं ) मैं लॉगफाइल चर के लिए विलंबित विस्तार का उपयोग करता हूं, इसलिए >> !logfile!इसके बजाय >> %logfile%सबरूटीन के भीतर। इस तरह, यह तब काम करता है जब एक कोड ब्लॉक के भीतर से कॉल किया जाता है (जैसे कि एक if स्टेटमेंट के भीतर)। 3) मैंने "सेट मैसेज" लाइन को हटा दिया क्योंकि अतिरिक्त चर की कोई आवश्यकता नहीं है। हमारे पास पहले से ही है, $~1इसलिए मेरे पास echo $~1दोनों इको कमांड के लिए है।
नाटे

2

मैंने एक सरल सी # कंसोल बनाया जो कि वास्तविक समय आउटपुट को cmd स्क्रीन और लॉग दोनों के लिए संभाल सकता है

class Tee
{
    static int Main(string[] args)
    {
        try
        {
            string logFilePath = Path.GetFullPath(args[0]);

            using (StreamWriter writer = new StreamWriter(logFilePath, true))
            {
                for (int value; (value = Console.In.Read()) != -1;)
                {
                    var word = Char.ConvertFromUtf32(value);
                    Console.Write(word);
                    writer.Write(word);
                }
            }
        }
        catch (Exception)
        {
            return 1;
        }
        return 0;
    }
}

बैच फ़ाइल का उपयोग उसी प्रकार है जैसे आप यूनिक्स का उपयोग करते हैं tee

foo | tee xxx.log

और यहाँ रिपॉजिटरी है जिसमें Tee.exe शामिल है अगर आपके पास https://github.com/iamsh//ee को संकलित करने के लिए उपकरण नहीं है


1

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


0

"टॉमस आर" द्वारा प्रदान किया गया समाधान ओपी के प्रश्न के लिए एकदम सही काम करता है और यह मूल रूप से उपलब्ध है।

कोशिश करें: chkdsk c:> output.txt | type.txt टाइप करें

आउटपुट इस कमांड का होता है जिसमें एक पूर्ण प्रतिशत शामिल होता है जो फ़ाइल में क्रमिक रूप से आउटपुट प्राप्त करता है इसलिए यह थोड़ा गड़बड़ दिखाई देगा (यानी पाठ प्रगति के रूप में जोड़ा जाएगा)। यह उन बिट्स के साथ नहीं होता है जो STDOUT (स्क्रीन) को आउटपुट देता है। यह है कि यह कैसे होगा यदि आप केवल पुनर्निर्देशन के बिना एक ही कमांड करते हैं।


-3

मुझे लगता है कि आप इस की तर्ज पर कुछ चाहते हैं:

echo Your Msg> YourTxtFile.txt

या यदि आप एक नई लाइन चाहते हैं:

echo Your Msg>> YourTxtFile.txt

ये कमांड लॉग्स के लिए बढ़िया हैं।

नोट: यह कभी-कभी गड़बड़ हो जाएगा और मेरे कंप्यूटर पर संपूर्ण पाठ फ़ाइल को बदल देगा।

एक और नोट: यदि फ़ाइल मौजूद नहीं है, तो यह फ़ाइल बनाएगी।


1
नहीं, ओपी एक फ़ाइल में और स्क्रीन पर उत्पादन करना चाहता था । तुम्हारा सिर्फ फाइल करने के लिए लिखता है। (और >है के लिए बनाया गया फ़ाइल को अधिलेखित करने के लिए प्रयोग करें। >>करने के लिए संलग्न )
स्टीफ़न
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.