แสดงคำสั่งของ Windows พร้อมท์เอาต์พุตและเปลี่ยนเส้นทางไปยังไฟล์


371

ฉันจะรันแอพพลิเคชั่นบรรทัดคำสั่งในพรอมต์คำสั่งของ Windows ได้อย่างไรและให้แสดงผลลัพธ์และเปลี่ยนเส้นทางไปยังไฟล์ในเวลาเดียวกันได้อย่างไร

ตัวอย่างเช่นถ้าฉันจะเรียกใช้คำสั่งdir > test.txtนี้จะเปลี่ยนเส้นทางการส่งออกไปยังไฟล์ที่เรียกว่าtest.txtโดยไม่แสดงผลลัพธ์

ฉันจะเขียนคำสั่งเพื่อแสดงเอาต์พุตและเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ในพรอมต์คำสั่ง Windows ได้เช่นเดียวกับteeคำสั่งบน Unix ได้อย่างไร


63
และโปรดหยุดเรียกมันว่า MSDOS! ความคล้ายคลึงกันระหว่าง cmd.exe และ comm คอมดีนั้นคือขนาดจิ๋วและเล็กลง
paxdiablo


ไม่มีการทำงานเหล่านี้หากมีแอปพลิเคชันคอนโซลที่โหลด dll ที่แสดงผลข้อความ ข้อความของแอปพลิเคชันหลักได้รับการเปลี่ยนเส้นทางไปยังไฟล์ แต่ผลลัพธ์จาก dll ไม่ได้และยังคงปรากฏในหน้าต่างคอนโซล ฉันไม่พบวิธีที่จะจับข้อความจาก dll
Brian Reinhold

1
หนึ่งสามารถยังเพียงแค่
ไพพ์

ถ้าฉันใช้ยูทิลิตี้บรรทัดคำสั่งและต้องการเปลี่ยนทิศทางเอาต์พุตไปยังไฟล์ในรูปแบบเดียวกับที่แสดงบนหน้าจอฉันใช้ youtube-dl เพื่อแยกลิงก์และสามารถเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ txt แต่ไม่ได้ฟอร์แมตเป็น คุณจะได้รับพร้อมท์ในไฟล์มาเป็นบรรทัดเดียว
beastboy

คำตอบ:


153

เพื่อขยายคำตอบของ davorคุณสามารถใช้ PowerShell ดังนี้:

powershell "dir | tee test.txt"

หากคุณพยายามเปลี่ยนเส้นทางเอาต์พุตของ exe ในไดเรกทอรีปัจจุบันคุณต้องใช้.\ชื่อไฟล์เช่น:

powershell ".\something.exe | tee test.txt"

8
นี่คือคำตอบที่ใกล้เคียงที่สุด: มันใช้งานได้กับการติดตั้งเริ่มต้นเนื่องจาก PS มีอยู่แล้วในเครื่องส่วนใหญ่และโดยเฉพาะเซิร์ฟเวอร์
Stoleg

1
นี่คือคำตอบที่ดีที่สุด! เรียบง่ายและใช้งานได้ "ออกจากกล่อง"
Josh Werts

3
LIKE IT :) อย่างไรก็ตาม {powershell "ping -n 10 localhost | tee test.txt"} จะแสดงให้เห็นว่าเกิดอะไรขึ้นในงานปาร์ตี้ทีดีกว่า
grenix

4
ทราบว่าdirใน PowerShell เป็นนามแฝงไปGet-ChildItemซึ่งไม่ได้เป็นเช่นภายใน cmd ของdirคำสั่ง คุณต้องการpowershell "cmd /c dir | tee test.txt"ถ้าคุณต้องการรุ่นภายใน cmd
phuclv

8
เพื่อดูการส่งออกทั้งหมดไม่ลืมที่จะเปลี่ยนเส้นทาง STDERR เพื่อ STDOUT ด้วย2>&1ตัวอย่างเช่นnode 2>&1 | tee debug_log.txt
Zhe Hu

132

ฉันสามารถค้นหาวิธีแก้ปัญหา / วิธีแก้ปัญหาของการเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์จากนั้นไปที่คอนโซล:

dir > a.txt | type a.txt

โดยที่dirเป็นคำสั่งที่เอาต์พุตต้องถูกเปลี่ยนเส้นทางa.txtไฟล์ที่เก็บเอาต์พุต


100
สิ่งนี้ตอบสนองคำตอบได้ แต่ส่งออกข้อมูลหลังจากคำสั่ง dir เสร็จสมบูรณ์แทนที่จะเป็นข้อมูลที่สร้างขึ้น
Leigh Riffel

10
มันจะทำงาน แต่คุณจะติดถ้าคำสั่งรออินพุตจาก stdin
Vitim.us

5
ฉันชอบคำตอบง่ายๆนี้! ฉันพบว่าจำเป็นต้องใช้การ&แทน a |สำหรับเอาต์พุตของคำสั่งบางคำเช่นpingหรือ7z.exe
Wes Larson

dirไม่ทำงานสำหรับคำสั่งแบบโต้ตอบแทน ตัวอย่าง: chkdsk /f c: > c:\Temp.txt | c:\Temp.txt. ไฟล์รายงานระบบถูกล็อคโดยกระบวนการอื่น
Sopalajo de Arrierez

4
@lii re: handle output to stderr- เพิ่มการ2>&1เปลี่ยนเส้นทางดังนั้นจึงเป็นเช่นนี้: dir 2>&1 > a.txt & type a.txtและคุณควรมี stderr ผสมกับ stdout
Jesse Chisholm

97

มีพอร์ต Win32 ของteeคำสั่งUnix ที่ทำเช่นนั้น ดูhttp://unxutils.sourceforge.net/หรือhttp://getgnuwin32.sourceforge.net/


17
ลิงก์ชี้ไปที่การนำไปใช้งาน Windows ของคำสั่ง Unix ดังนั้นจึงทำงานบน Windows
Brian Rasmussen

3
ใช่โหวตคำตอบและความคิดเห็น ฉันชอบ CygWin จริง ๆ เพราะมีทุกอย่าง แต่บางคนชอบเครื่องมือที่ไม่ใช่ DLL ที่พวกเขาสามารถเลือกและเลือกได้
paxdiablo

3
จำนวนมากของสาธารณูปโภคยูนิกซ์ยังรังเพลิงโครงการ GnuWin32 ดูgnuwin32.sourceforge.net
VladV

2
UnxUtils ได้รับการปรับปรุงล่าสุดในปี 2003; GnuWin32 เป็นข้อมูลที่ทันสมัยมากขึ้นอีกเล็กน้อย
ต้มตุ๋น quixote

9
ถ้าคุณชอบก็พยายามที่จะหา GnuWin32 ของteeแพคเกจที่คุณจะหาได้ในgnuwin32.sourceforge.net/packages/coreutils.htm
ไนเจล Touch

49

ลองดูสิ: wintee

ไม่จำเป็นต้องมี cygwin

ฉันพบและรายงานปัญหาบางอย่างแล้ว

นอกจากนี้คุณอาจตรวจสอบunxutilsเพราะมันมี tee (และไม่จำเป็นต้อง cygwin) แต่ระวังว่า output EOL นั้นเป็น UNIX เหมือนที่นี่

สุดท้าย แต่ไม่ท้ายสุดคือถ้าคุณมี PowerShell คุณสามารถลองใช้ Tee-Object พิมพ์get-help tee-objectใน PowerShell console สำหรับข้อมูลเพิ่มเติม


4
ทำไมถึงลงคะแนน? 95% ของการตอบกลับที่นี่มีสิ่งหนึ่งที่เหมือนกัน: เอาต์พุตจะถูกเปลี่ยนเส้นทางหลังจากคำสั่งเริ่มต้นเสร็จสิ้น: อ่านความคิดเห็น ยูทิลิตี UNIX teeแสดงผลตามเวลาจริง wteeมีฟังก์ชั่นเดียวกัน หากคุณไม่รังเกียจข้อบกพร่องมันจะทำได้ดี
Davor Josipovic

นั่นเป็นทางออกเดียวสำหรับฉันที่ไม่มี Powershell> 4.0 ยกนิ้ว!
อเล็กซ์

46

@ tori3852

ฉันพบว่า

dir > a.txt | type a.txt

ไม่ทำงาน (ไม่กี่บรรทัดแรกของรายการ dir เท่านั้น - สงสัยว่ากระบวนการฟอร์กกิ้งบางประเภทและส่วนที่สองคำสั่ง 'type' ถูกยกเลิกก่อนที่รายการไดเร็คต์จะเสร็จสมบูรณ์?) ดังนั้นฉันจึงใช้:

dir > z.txt && type z.txt

ซึ่งทำ - คำสั่งต่อเนื่องหนึ่งเสร็จสมบูรณ์ก่อนที่สองเริ่ม


17
คุณควรใช้&แทน&&หากคุณต้องการให้แน่ใจว่าtypeคำสั่งถูกดำเนินการแม้ว่าdirคำสั่งล้มเหลว สิ่งนี้มีประโยชน์เมื่อมีข้อผิดพลาดบางรูปแบบในคำสั่งของคุณและคุณยังต้องการดูไฟล์บันทึกบนคอนโซล ดูบทความไมโครซอฟท์เกี่ยวกับเรื่องนี้ อย่างไรก็ตามปัญหานี้มีปัญหาใน%errorlevel%การตั้งค่าเป็นระดับข้อผิดพลาดของtype(ซึ่งจะเป็น 0)
ADTC

25

น่าเสียดายที่ไม่มีสิ่งนั้น

แอปพลิเคชันคอนโซล Windows มีหมายเลขอ้างอิงผลลัพธ์เดียวเท่านั้น (ดีมีสองSTDOUT, STDERRแต่มันไม่ได้เรื่องที่นี่) ด้วย>การเปลี่ยนเส้นทางการส่งออกที่เขียนตามปกติในการจับคอนโซลเพื่อจัดการไฟล์

หากคุณต้องการมัลติเพล็กซ์บางประเภทคุณต้องใช้แอปพลิเคชันภายนอกซึ่งคุณสามารถเบี่ยงเบนความสนใจไปที่เอาต์พุต แอปพลิเคชันนี้สามารถเขียนไปยังไฟล์และคอนโซลอีกครั้ง


3
teeบนระวัง * นอกจากนี้ยังเป็นแอพลิเคชันที่แยกจากกันไม่ได้เปลี่ยนเส้นทางบางส่วนในเปลือก
phuclv

22

แอปพลิเคชันคอนโซล C # แบบง่ายจะทำการหลอกลวง:

using System;
using System.Collections.Generic;
using System.IO;

namespace CopyToFiles
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = new char[100];
            var outputs = new List<TextWriter>();

            foreach (var file in args)
                outputs.Add(new StreamWriter(file));

            outputs.Add(Console.Out);

            int bytesRead;
            do
            {
                bytesRead = Console.In.ReadBlock(buffer, 0, buffer.Length);
                outputs.ForEach(o => o.Write(buffer, 0, bytesRead));
            } while (bytesRead == buffer.Length);

            outputs.ForEach(o => o.Close());
        }
    }
}

ในการใช้สิ่งนี้คุณเพียงแค่ไพพ์คำสั่ง source ลงในโปรแกรมและจัดเตรียมพา ธ ของไฟล์ใด ๆ ที่คุณต้องการทำซ้ำเอาต์พุต ตัวอย่างเช่น:

dir | CopyToFiles files1.txt files2.txt 

จะแสดงผลลัพธ์ของ dir รวมถึงเก็บผลลัพธ์ไว้ในทั้ง files1.txt และ files2.txt

โปรดทราบว่าการจัดการข้อผิดพลาดมีไม่มาก (อะไร!) ด้านบนและอาจไม่จำเป็นต้องรองรับไฟล์หลายไฟล์


5
อืมดาวน์โหลดที / cygwin โดยไม่ซื้ออะไรเลยหรือซื้อ MSVS ด้วยเงินสดที่หาได้ยากสำหรับโปรแกรมเล็ก ๆ แบบนี้ นั่นเป็นหนึ่งยาก :-)
paxdiablo

19
คุณไม่จำเป็นต้องใช้ Visual Studio ในการรวบรวมเครื่องมือ commandline นั้นฟรี เพียงแค่ google ".net sdk download" สำหรับลิงก์ (ลิงก์โดยตรงดูเหมือนว่าจะเปลี่ยนไป แต่ google มักจะใช้งานได้)
คริส

13
Visual Studio Express ฟรีเช่นกัน แต่ฉันจะยังคงใช้ tee สำหรับสิ่งนี้
Brian Rasmussen

7
cygwin เป็นความเจ็บปวดในการติดตั้ง โหวตให้คุณเพราะนี่คือสิ่งที่ฉันกำลังมองหา
Samaursa

1
ฉันไม่คิดว่าสิ่งนี้จะส่งออกไปยังคอนโซลและไฟล์ในเวลาเดียวกันได้หรือไม่
mjaggard

20

ใช้งานได้แม้ว่ามันจะน่าเกลียดสักหน่อย:

dir >_ && type _ && type _ > a.txt

มีความยืดหยุ่นมากกว่าโซลูชันอื่น ๆ เล็กน้อยเนื่องจากสามารถใช้คำสั่งต่อคำสั่งเพื่อให้คุณสามารถใช้ผนวกเข้าด้วยกัน ฉันใช้สิ่งนี้ในไฟล์แบตช์เล็กน้อยเพื่อบันทึกและแสดงข้อความ:

ECHO Print line to screen and log to file.  >_ && type _ && type _ >> logfile.txt

ใช่คุณสามารถทำซ้ำคำสั่ง ECHO (หนึ่งครั้งสำหรับหน้าจอและครั้งที่สองที่เปลี่ยนเส้นทางไปยังไฟล์บันทึก) แต่นั่นดูเหมือนจะไม่ดีและเป็นปัญหาการบำรุงรักษาเล็กน้อย อย่างน้อยคุณก็ไม่ต้องทำการเปลี่ยนแปลงข้อความในสองที่นี้

โปรดทราบว่า _ เป็นเพียงชื่อไฟล์สั้น ๆ ดังนั้นคุณจะต้องตรวจสอบให้แน่ใจว่าได้ลบที่ท้ายแบทช์ไฟล์ (ถ้าคุณใช้แบตช์ไฟล์)


2
มีประโยชน์เฉพาะถ้าคุณต้องการแสดงเนื้อหาหลังจากกระบวนการของคุณทำงาน และนั่นไม่ใช่ปัญหายากที่จะแก้ไข
Christopher Painter

1
ใช่ฉันเดาว่านี่เป็นปัญหาที่แตกต่างเล็กน้อยจากสิ่งที่ผู้ถามเดิมถาม
MTS

1
+1 นี่คือสิ่งที่ฉันทำมาตลอด ฉันเชื่อว่านี่เป็นคำตอบที่ถูกต้องสำหรับคำถามต้นฉบับและควรได้รับการระบุว่าเป็นเช่นนั้น เคล็ดลับตามที่ @MTS บอกเป็นนัยก็คือคุณเขียนไปยังไฟล์สองไฟล์: ไฟล์ที่ถูกสร้างขึ้นสำหรับแต่ละคำสั่ง / บรรทัด (ดังนั้น ">" ที่เขียนทับแต่ละครั้ง) จากนั้นคุณพิมพ์บรรทัดนั้นลงบนหน้าจอ ( พิมพ์) และในที่สุดคุณพิมพ์อีกครั้งและเปลี่ยนเส้นทางผลลัพธ์ทั้งหมดที่ยาวผนวกไปยังไฟล์บันทึกของคุณด้วย ">>" นี่คือวิธีที่ฉันทำมาหลายปีแม้ว่าฉันจะชอบไฟล์ชั่วคราว "" ฉันทำ "tmp.txt" หรือสิ่งของทุกอย่างแล้ว ใช่ลบทิ้งในภายหลัง
eduncan911

นี่เป็นวิธีการที่ดี แต่ฉันมีปัญหากับข้อผิดพลาดบางอย่างที่ไม่ถูกดักจับ การวางtypeคำสั่งบนบรรทัดแยก (ในรูทีนย่อย) แก้ไขว่า
Nate Cook

สิ่งที่ฉันต้องการสำหรับแอปพลิเคชันของฉัน
อลัน

16

mtee เป็นเครื่องมือขนาดเล็กที่ทำงานได้ดีมากสำหรับวัตถุประสงค์นี้ แหล่งที่มาเปิดฟรีและใช้งานได้ฟรี

คุณสามารถค้นหาได้ที่ http://www.commandline.co.uk

ใช้ในไฟล์แบตช์เพื่อแสดงเอาต์พุตและสร้างล็อกไฟล์พร้อมกันไวยากรณ์มีลักษณะดังนี้:

    someprocess | mtee /+ mylogfile.txt

โดยที่ / + หมายถึงการผนวกเอาต์พุต

นี่ถือว่าคุณได้คัดลอก mtee ไปไว้ในโฟลเดอร์ที่อยู่ใน PATH แน่นอน


1
ดูเหมือนว่าจะรอจนกว่าเอาต์พุตจะเสร็จสมบูรณ์ก่อนที่จะส่งออกไปยังไฟล์หรือคอนโซล
mellamokb

14

ฉันต้องการที่จะขยายบิตแซกซอน Druce ของคำตอบที่ดี

ตามที่ระบุไว้คุณสามารถเปลี่ยนทิศทางเอาต์พุตของไฟล์เรียกทำงานในไดเร็กทอรีปัจจุบันดังนี้:

powershell ".\something.exe | tee test.txt"

แต่นี้เข้าสู่ระบบเพื่อstdout มันไม่ได้นอกจากนี้ยังเข้าสู่ระบบtest.txtstderr

ทางออกที่ชัดเจนคือการใช้สิ่งนี้:

powershell ".\something.exe 2>&1 | tee test.txt"

แต่นี้จะไม่ทำงานสำหรับทุกsomething.exes บางคนsomething.exeจะตีความ2>&1ว่าเป็นข้อโต้แย้งและล้มเหลว วิธีแก้ไขที่ถูกต้องคือแทนที่จะมีเครื่องหมายอัญประกาศเดี่ยวรอบ ๆsomething.exeและสวิตช์และอาร์กิวเมนต์ของมันเท่านั้นเช่น:

powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt

ฉันลองสิ่งนี้เมื่อสร้าง pyqt5.7 บน windows 10 มันค่อนข้างเชื่องช้าคอนโซลเอาต์พุตไม่เรียลไทม์บางทีมันอาจจะถูกบัฟเฟอร์? ไฟล์บันทึกนั้นดูถูกต้องแล้ว
Shuman

3
ทั้งหมดนี้เป็นสิ่งที่ผิดอย่างสมบูรณ์ มันไม่ทำงานเลยสำหรับฉัน คำสั่งสุดท้ายให้'tee' is not recognized as an internal or external commandเหตุผลที่ชัดเจน ด้วย2>&1cmd ภายในบรรทัดเอาต์พุตใด ๆ ไปยัง stderr ทำให้เกิดข้อผิดพลาดจาก powershell
Pavel P

อาจเป็นการอ้างอิงถึง PowerShell Tee-Object cmdlet - technet.microsoft.com/en-us/library/ee177014.aspx
Bernd

9

ฉันเห็นด้วยกับ Brian Rasmussen พอร์ต unxutils เป็นวิธีที่ง่ายที่สุดในการทำเช่นนี้ ในส่วนBatch Filesของหน้าสคริปต์ของเขาRob van der Woude ให้ข้อมูลมากมายเกี่ยวกับการใช้คำสั่ง MS-DOS และ CMD ฉันคิดว่าเขาอาจมีทางแก้ปัญหาของคุณและหลังจากขุดไปที่นั่นฉันพบTEE.BATซึ่งดูเหมือนจะเป็นเช่นนั้นการใช้ภาษาชุดแบ็ตช์ของ MS-DOS มันเป็นไฟล์แบทช์ที่ดูค่อนข้างซับซ้อนและความชอบของฉันจะยังคงใช้พอร์ต unxutils


สิ่งที. ค้างคาวดูดี Hope OP ตรวจสอบสิ่งนี้
Jay

10
โปรดทราบว่าการใช้ TEE.BAT จะส่งออกหลังจากคำสั่งเสร็จสิ้นเช่นเดียวกับตัวอย่าง "dir> a.txt | type a.txt" ที่โพสต์ใกล้เคียง
adzm

8

หากคุณมี cygwin ในเส้นทางสภาพแวดล้อมของ windows คุณสามารถใช้:

 dir > a.txt | tail -f a.txt

7
หากคุณจะใช้ Cygwin มันมาพร้อมกับที
นายลามะ

7

dir 1>a.txt 2>&1 | type a.txt

สิ่งนี้จะช่วยในการเปลี่ยนเส้นทางทั้ง STDOUT และ STDERR


มันใช้งานไม่ได้ ฉันพยายามใช้สิ่งนี้เพื่อเปิด JBoss run.bat และมันโช้กระหว่างการเริ่มต้นและเซิร์ฟเวอร์ค้าง มีปัญหากับวิธีนี้ ...
djangofan

@raja ashok ไม่ได้ผลสำหรับฉัน ฉันลองpython.exe 1> file.txt 2> & 1 | พิมพ์ file.txt
ใหม่

4

ฉันรู้ว่านี่เป็นหัวข้อที่เก่ามาก แต่ในคำตอบก่อนหน้านี้ไม่มีการนำ Tee แบบเรียลไทม์มาเขียนในแบทช์ โซลูชันด้านล่างของฉันคือสคริปต์ไฮบริด Batch-JScript ที่ใช้ส่วน JScript เพียงเพื่อรับเอาต์พุตจากคำสั่ง piped แต่การประมวลผลข้อมูลจะทำในส่วน Batch วิธีการนี้มีข้อได้เปรียบที่โปรแกรมเมอร์ Batch ใด ๆ อาจแก้ไขโปรแกรมนี้ให้เหมาะสมกับความต้องการเฉพาะ โปรแกรมนี้ยังประมวลผลเอาต์พุตของคำสั่ง CLS ที่สร้างโดยไฟล์ Batch อื่นอย่างถูกต้องนั่นคือจะล้างหน้าจอเมื่อตรวจพบเอาต์พุตคำสั่ง CLS

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion

rem APATee.bat: Asynchronous (real time) Tee program, Batch-JScript hybrid version
rem Antonio Perez Ayala

rem The advantage of this program is that the data management is written in Batch code,
rem so any Batch programmer may modify it to fit their own needs.
rem As an example of this feature, CLS command is correctly managed

if "%~1" equ "" (
   echo Duplicate the Stdout output of a command in the screen and a disk file
   echo/
   echo anyCommand ^| APATee teeFile.txt [/A]
   echo/
   echo If /A switch is given, anyCommand output is *appended* to teeFile.txt
   goto :EOF
)

if "%2" equ ":TeeProcess" goto TeeProcess

rem Get the output of CLS command
for /F %%a in ('cls') do set "cls=%%a"

rem If /A switch is not provided, delete the file that receives Tee output
if /I "%~2" neq "/A" if exist %1 del %1

rem Create the semaphore-signal file and start the asynchronous Tee process
echo X > Flag.out
if exist Flag.in del Flag.in
Cscript //nologo //E:JScript "%~F0" | "%~F0" %1 :TeeProcess
del Flag.out
goto :EOF

:TeeProcess
   rem Wait for "Data Available" signal
   if not exist Flag.in goto TeeProcess
   rem Read the line sent by JScript section
   set line=
   set /P line=
   rem Set "Data Read" acknowledgement
   ren Flag.in Flag.out
   rem Check for the standard "End Of piped File" mark
   if "!line!" equ ":_EOF_:" exit /B
   rem Correctly manage CLS command
   if "!line:~0,1!" equ "!cls!" (
      cls
      set "line=!line:~1!"
   )
   rem Duplicate the line in Stdout and the Tee output file
   echo(!line!
   echo(!line!>> %1
goto TeeProcess


@end


// JScript section

var fso = new ActiveXObject("Scripting.FileSystemObject");
// Process all lines of Stdin
while ( ! WScript.Stdin.AtEndOfStream ) {
   // Read the next line from Stdin
   var line = WScript.Stdin.ReadLine();
   // Wait for "Data Read" acknowledgement
   while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
   }
   // Send the line to Batch section
   WScript.Stdout.WriteLine(line);
   // Set "Data Available" signal
   fso.MoveFile("Flag.out", "Flag.in");
}
// Wait for last "Data Read" acknowledgement
while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
}
// Send the standard "End Of piped File" mark
WScript.Stdout.WriteLine(":_EOF_:");
fso.MoveFile("Flag.out", "Flag.in");

วิธีนี้สามารถจับเอาท์พุท stderr? ฉันมี exe ที่น่ารำคาญที่ส่งออกทุกอย่างในสตรีมข้อผิดพลาดมาตรฐาน (เช่นเพื่อส่งออกไปยังไฟล์ตามปกติคุณจะทำfile.exe 2>output.txt
Mark Deven

ฉันคิดออก คุณสามารถทำได้โดยใช้file.exe 2>&1|tee.batที่นี่: superuser.com/questions/452763/…
Mark Deven

4

ฉันยังมองหาวิธีการแก้ปัญหาเดียวกันหลังจากลองเล็ก ๆ น้อย ๆ ฉันก็สามารถประสบความสำเร็จได้ใน Command Prompt นี่คือทางออกของฉัน:

@Echo off
for /f "Delims=" %%a IN (xyz.bat) do (
%%a > _ && type _ && type _ >> log.txt
)
@Echo on

มันยังจับคำสั่งหยุดชั่วคราวใด ๆ เช่นกัน


3

นี่คือตัวอย่างของสิ่งที่ฉันใช้ตามคำตอบอย่างอื่น

@echo off
REM SOME CODE
set __ERROR_LOG=c:\errors.txt
REM set __IPADDRESS=x.x.x.x

REM Test a variable
if not defined __IPADDRESS (
     REM Call function with some data and terminate
     call :TEE %DATE%,%TIME%,IP ADDRESS IS NOT DEFINED
     goto :EOF
)

REM If test happens to be successful, TEE out a message and end script.
call :TEE Script Ended Successful
goto :EOF


REM THE TEE FUNCTION
:TEE
for /f "tokens=*" %%Z in ("%*") do (
     >  CON ECHO.%%Z
     >> "%__ERROR_LOG%" ECHO.%%Z
     goto :EOF
)

3

สิ่งนี้ควรทำในสิ่งที่คุณต้องการ?

%DATE%_%TIME% > c:\a.txt & type c:\a.txt
ipconfig >> c:\a.txt & type c:\a.txt
ping localhost >> c:\a.txt & type c:\a.txt
pause

เกือบ แต่จะไม่แสดงพร้อมกัน - หากคุณมีงานที่ต้องทำนาน ๆ คุณจะไม่ได้รับผลลัพธ์เป็นเวลานาน
JustAMartin

3

ส่งออกไปยังคอนโซลผนวกกับบันทึกคอนโซลลบออกจากคำสั่งปัจจุบัน

dir  >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1

8
สนใจที่จะอธิบายสิ่งที่เกิดขึ้นที่นี่?
John Demetriou

2

นี่เป็นรูปแบบของคำตอบก่อนหน้าโดย MTS อย่างไรก็ตามมันเพิ่มฟังก์ชันการทำงานบางอย่างที่อาจเป็นประโยชน์กับผู้อื่น นี่คือวิธีการที่ฉันใช้:

  • คำสั่งถูกตั้งค่าเป็นตัวแปรที่สามารถใช้ได้ในภายหลังตลอดทั้งรหัสเพื่อส่งออกไปยังหน้าต่างคำสั่งและผนวกเข้ากับไฟล์บันทึกโดยใช้ set _Temp_Msg_Cmd=
    • คำสั่งหนีการเปลี่ยนเส้นทางโดยใช้^ตัวอักษรแครอทเพื่อไม่ให้ประเมินคำสั่งในตอนแรก
  • ไฟล์ชั่วคราวถูกสร้างด้วยชื่อไฟล์ที่คล้ายกับไฟล์แบตช์ที่กำลังเรียก%~n0_temp.txtใช้ซึ่งใช้ไวยากรณ์ส่วนขยายพารามิเตอร์บรรทัดคำสั่ง %~n0เพื่อรับชื่อของไฟล์แบตช์
  • ผลลัพธ์จะถูกผนวกเข้ากับไฟล์บันทึกแยกต่างหาก %~n0_log.txt

นี่คือลำดับของคำสั่ง:

  1. เอาต์พุตและข้อความแสดงความผิดพลาดถูกส่งไปยังไฟล์ชั่วคราว ^> %~n0_temp.txt 2^>^&1
  2. เนื้อหาของไฟล์ชั่วคราวนั้นทั้งคู่:
    • ผนวกเข้ากับล็อกไฟล์ ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • ส่งออกไปยังหน้าต่างคำสั่ง ^& type %~n0_temp.txt
  3. ไฟล์ชั่วคราวพร้อมข้อความถูกลบ ^& del /Q /F %~n0_temp.txt

นี่คือตัวอย่าง:

set _Temp_Msg_Cmd= ^> %~n0_temp.txt 2^>^&1 ^& type %~n0_temp.txt ^>^> %~n0_log.txt ^& type %~n0_temp.txt ^& del /Q /F %~n0_temp.txt

ด้วยวิธีนี้แล้วคำสั่งสามารถต่อท้ายหลังจากคำสั่งในภายหลังในไฟล์แบทช์ที่ดูสะอาดกว่ามาก:

echo test message %_Temp_Msg_Cmd%

สิ่งนี้สามารถเพิ่มลงในส่วนท้ายของคำสั่งอื่นเช่นกัน เท่าที่ฉันสามารถบอกได้ว่ามันจะทำงานเมื่อข้อความมีหลายบรรทัด ตัวอย่างเช่นคำสั่งต่อไปนี้จะออกสองบรรทัดหากมีข้อผิดพลาด:

net use M: /D /Y %_Temp_Msg_Cmd%


1
@echo on

set startDate=%date%
set startTime=%time%

set /a sth=%startTime:~0,2%
set /a stm=1%startTime:~3,2% - 100
set /a sts=1%startTime:~6,2% - 100


fullprocess.bat > C:\LOGS\%startDate%_%sth%.%stm%.%sts%.LOG | fullprocess.bat

สิ่งนี้จะสร้างไฟล์บันทึกที่มีวันที่และเวลาปัจจุบันและคุณสามารถบรรทัดคอนโซลในระหว่างกระบวนการ


11
คุณไม่ได้เรียกโปรแกรมเดียวกันสองครั้งด้วยสิ่งนี้ใช่หรือไม่
elcool

1

ฉันใช้รูทีนย่อยชุดคำสั่ง "for" เพื่อรับเอาต์พุตคำสั่งทีละบรรทัดและทั้งคู่เขียนบรรทัดนั้นไปยังไฟล์และส่งออกไปยังคอนโซล

@echo off
set logfile=test.log

call :ExecuteAndTee dir C:\Program Files

Exit /B 0

:ExecuteAndTee
setlocal enabledelayedexpansion
echo Executing '%*'
  for /f "delims=" %%a in ('%* 2^>^&1') do (echo.%%a & echo.%%a>>%logfile%)
endlocal
Exit /B 0

ฉันทำเช่นเดียวกันเมื่อพยายามที่จะจับเอาท์พุทจากคำสั่ง (IE ใส่ไว้ในสำหรับ) แต่จากนั้นฉันก็เรียกฟังก์ชั่นย่อยมาตรฐานของฉันเพื่อสะท้อนไปยังหน้าจอและเขียนลงในบันทึกเพราะฉันใช้มันตลอดสคริปต์ของฉัน . ไม่แน่ใจว่าเพราะเหตุใดจึงมีการลงคะแนนจากผู้อื่นดังนั้นฉันจึงลงคะแนน
Ben Personick

1

หากคุณอยู่ใน CLI ทำไมไม่ใช้ FOR loop เพื่อ "DO" สิ่งที่คุณต้องการ:

for /F "delims=" %a in ('dir') do @echo %a && echo %a >> output.txt

ทรัพยากรที่ยอดเยี่ยมสำหรับ Windows CMD สำหรับลูป: https://ss64.com/nt/for_cmd.html กุญแจสำคัญในที่นี้คือการตั้งค่าตัวคั่น (delims) ที่จะแยกเอาท์พุทแต่ละบรรทัดออกเป็นไม่มีอะไร วิธีนี้จะไม่ทำให้ค่าเริ่มต้นของ white-space แตก % a เป็นตัวอักษรตามอำเภอใจ แต่มันถูกใช้ในส่วน "do" ถึงดี ... ทำบางสิ่งบางอย่างกับตัวอักษรที่แยกวิเคราะห์ในแต่ละบรรทัด ในกรณีนี้เราสามารถใช้เครื่องหมายแอมเปอร์แซนด์ (&&) เพื่อรันคำสั่ง echo ลำดับที่ 2 เพื่อสร้างหรือต่อท้าย (>>) ไปยังไฟล์ที่เราเลือก ปลอดภัยกว่าเพื่อรักษาคำสั่ง DO นี้ในกรณีที่มีปัญหาในการเขียนไฟล์อย่างน้อยเราจะนำเสียงก้องไปยังคอนโซลก่อน เครื่องหมาย at (@) ที่อยู่ด้านหน้าของ echo แรกช่วยไม่ให้คอนโซลแสดงคำสั่ง echo เองและเพียงแสดงผลลัพธ์ของคำสั่งที่จะแสดงอักขระใน% a มิฉะนั้นคุณจะเห็น:

echo Volume ในไดรฟ์ [x] คือ Windows
Volume ในไดรฟ์ [x] คือ Windows

UPDATE: / F ข้ามบรรทัดว่างเปล่าและแก้ไขเพียงอย่างเดียวคือกรองเอาท์พุทล่วงหน้าที่เพิ่มอักขระให้กับทุกบรรทัด (อาจมีหมายเลขบรรทัดผ่านการค้นหาคำสั่ง) การแก้ปัญหานี้ใน CLI นั้นไม่รวดเร็วหรือสวย นอกจากนี้ฉันไม่ได้รวม STDERR ดังนั้นนี่คือข้อผิดพลาดในการจับภาพเช่นกัน:

for /F "delims=" %a in ('dir 2^>^&1') do @echo %a & echo %a >> output.txt

การเปลี่ยนเส้นทางข้อความผิดพลาด

เครื่องหมายคาร์เร็ต (^) อยู่ที่นั่นเพื่อหนีสัญลักษณ์หลังจากพวกมันเนื่องจากคำสั่งเป็นสตริงที่ถูกตีความซึ่งต่างจากการพูดให้ป้อนมันโดยตรงบนบรรทัดคำสั่ง


1

เหมือนยูนิกซ์

dir | tee a.txt

ทำงานบน windows XP ต้องmksntติดตั้ง

มันจะแสดงขึ้นบนพรอมต์เช่นเดียวกับผนวกเข้ากับไฟล์


0

การติดตามช่วยหากคุณต้องการสิ่งที่เห็นบนหน้าจอจริงๆ - แม้ว่าไฟล์แบตช์จะถูกเปลี่ยนเส้นทางไปยังไฟล์ อุปกรณ์ CON อาจใช้หากเปลี่ยนเส้นทางไปยังไฟล์

ตัวอย่าง:

ECHO first line on normal stdout. maybe redirected
ECHO second line on normal stdout again. maybe redirected
ECHO third line is to ask the user. not redirected  >CON
ECHO fourth line on normal stdout again. maybe redirected

ดูคำอธิบายการเปลี่ยนเส้นทางที่ดี: http://www.p-dd.com/chapter7-page14.html


0

ฉันจะแสดงและเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์ได้อย่างไร สมมติว่าถ้าฉันใช้คำสั่ง dos, dir> test.txt คำสั่งนี้จะเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์ test.txt โดยไม่แสดงผลลัพธ์ วิธีการเขียนคำสั่งเพื่อแสดงผลลัพธ์และเปลี่ยนเส้นทางไปยังไฟล์โดยใช้ DOS เช่นคำสั่ง windows command ไม่ใช่ใน UNIX / LINUX

คุณอาจพบคำสั่งเหล่านี้ใน biterscripting ( http://www.biterscripting.com ) มีประโยชน์

var str output
lf > $output
echo $output                            # Will show output on screen.
echo $output > "test.txt"               # Will write output to file test.txt.
system start "test.txt"                 # Will open file test.txt for viewing/editing.

0

ใช้งานได้ในเวลาจริง แต่ก็น่าเกลียดและประสิทธิภาพก็ช้า ไม่ผ่านการทดสอบอย่างดี:

@echo off
cls
SET MYCOMMAND=dir /B
ECHO File called 'test.bat' > out.txt
for /f "usebackq delims=" %%I in (`%MYCOMMAND%`) do (
  ECHO %%I
  ECHO %%I >> out.txt
) 
pause

6
ไม่ไม่ใช่เวลาจริงรอจนกว่า%MYCOMMAND%จะเสร็จสิ้นและล้มเหลวในหลายกรณี มันข้ามเส้นที่ว่างเปล่าเส้นเริ่มต้นด้วยการ;ล้มเหลวด้วยเนื้อหาเช่น<space>/<TAB>, ON, หรือOFF /?แต่บางครั้งส่วนที่เหลือสามารถทำงานได้ :-)
jeb

0

อีกทางเลือกหนึ่งคือการที stdout ไปยัง stderr ภายในโปรแกรมของคุณ:

ใน java:

System.setOut(new PrintStream(new TeeOutputStream(System.out, System.err)));

จากนั้นในไฟล์ batch batch ของคุณ: java program > log.txt

stdout จะไปที่ logfile และ stderr (ข้อมูลเดียวกัน) จะแสดงบนคอนโซล


0

ฉันติดตั้ง Perl ในเครื่องส่วนใหญ่ของฉันดังนั้นคำตอบโดยใช้ Perl: tee.pl

my $file = shift || "tee.dat";
open $output, ">", $file or die "unable to open $file as output: $!";
while(<STDIN>)
{
    print $_;
    print $output $_;
}
close $output;

ผบ perl tee.pl หรือ dir | perl tee.pl dir.bat

น้ำมันดิบและยังไม่ทดลอง


0

อีกรูปแบบหนึ่งคือแยกท่อจากนั้นกำหนดทิศทางเอาต์พุตตามที่คุณต้องการอีกครั้ง

    @echo off
    for /f "tokens=1,* delims=:" %%P in ('findstr /n "^"') do (
      echo(%%Q
      echo(%%Q>&3
    )
    @exit/b %errorlevel%

บันทึกด้านบนเป็นไฟล์. bat มันแยกเอาท์พุทข้อความบน filestream 1 ถึง filestream 3 ด้วยซึ่งคุณสามารถเปลี่ยนเส้นทางได้ตามต้องการ ในตัวอย่างด้านล่างของฉันฉันเรียกสคริปต์ข้างต้น splitPipe.bat ...

    dir | splitPipe.bat  1>con  2>&1  3>my_stdout.log

    splitPipe.bat 2>nul < somefile.txt

-1
  1. https://cygwin.com/install
  2. คลิกลิงก์สำหรับ "setup-x86_.exe"
  3. เรียกใช้โปรแกรมติดตั้ง
  4. ในหน้า ~ 2nd เลือก "mirror" เพื่อดาวน์โหลดจาก (ฉันค้นหาโดเมน. edu)
  5. ฉันบอกว่าโอเคกับตัวเลือกมาตรฐาน
  6. Cygwin เสร็จสิ้นการติดตั้งอย่างรวดเร็ว
  7. เปิด cmd
  8. พิมพ์c:\cygwin64\bin\script.exeและป้อน
  9. พิมพ์cmdและป้อน
  10. เรียกใช้โปรแกรมของคุณ
  11. พิมพ์exitและป้อน (ออกจาก Cygwin's cmd.exe)
  12. พิมพ์exitและป้อน (ออกจาก script.exe ของ Cygwin)
  13. ดูผลลัพธ์หน้าจอของโปรแกรมของคุณในไฟล์ข้อความชื่อ "typescript"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.