Hiển thị đầu ra lệnh Windows và chuyển hướng nó đến một tệp


371

Làm cách nào tôi có thể chạy ứng dụng dòng lệnh trong dấu nhắc lệnh của Windows và có đầu ra được hiển thị và chuyển hướng đến một tệp cùng một lúc?

Ví dụ, nếu tôi chạy lệnh dir > test.txt, điều này sẽ chuyển hướng đầu ra đến một tệp được gọi test.txtmà không hiển thị kết quả.

Làm thế nào tôi có thể viết một lệnh để hiển thị đầu ra chuyển hướng đầu ra sang một tệp trong dấu nhắc lệnh của Windows, tương tự như teelệnh trên Unix?


63
Và xin vui lòng ngừng gọi nó là MSDOS! Điểm tương đồng giữa cmd.exe và lệnh braindead đó là rất nhỏ và ngày càng nhỏ hơn.
paxdiablo


Không ai trong số này hoạt động nếu ai đó có ứng dụng giao diện điều khiển tải một dll xuất văn bản. Văn bản ứng dụng chính được chuyển hướng đến một tệp nhưng đầu ra từ dll thì không và tiếp tục được hiển thị trong cửa sổ giao diện điều khiển. Tôi đã tìm thấy KHÔNG có cách nào để chụp văn bản từ dll.
Brian Reinhold

1
người ta vẫn có thể chuyển vào một tệp và sử dụng đuôi ( stackoverflow.com/questions/187587/ trên) trên tệp đó
x29a

Điều gì xảy ra nếu tôi đang sử dụng tiện ích dòng lệnh và muốn chuyển hướng đầu ra sang một tệp có định dạng chính xác như được hiển thị trên màn hình, tôi đã sử dụng youtube-dl để trích xuất các liên kết và có thể chuyển hướng đầu ra sang tệp txt, nhưng nó không được định dạng như bạn sẽ nhận được lời nhắc, trong tệp sắp tới là một dòng.
Beastboy

Câu trả lời:


153

Để mở rộng câu trả lời của davor , bạn có thể sử dụng PowerShell như thế này:

powershell "dir | tee test.txt"

Nếu bạn đang cố chuyển hướng đầu ra của một exe trong thư mục hiện tại, bạn cần sử dụng .\tên tệp, ví dụ:

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

8
Đây là câu trả lời gần nhất: nó hoạt động trên cài đặt mặc định, vì PS đã có trên hầu hết các máy và đặc biệt là các máy chủ.
Stoleg

1
Đây là câu trả lời tốt nhất! Đơn giản và hoạt động "ngoài
luồng

3
THÍCH NÓ :) dù sao đi nữa {powershell "ping -n 10 localhost | tee test.txt"} sẽ chứng minh rõ hơn những gì đang diễn ra trong bữa tiệc tee
grenix

4
lưu ý rằng dirtrong powershell là một bí danh Get-ChildItemkhông giống như dirlệnh nội bộ của cmd . Bạn cần powershell "cmd /c dir | tee test.txt"nếu bạn muốn phiên bản nội bộ cmd
phuclv

8
để xem tất cả đầu ra, đừng quên chuyển hướng STDERR sang STDOUT 2>&1, ví dụnode 2>&1 | tee debug_log.txt
Zhe Hu

132

Tôi đã có thể tìm một giải pháp / cách giải quyết chuyển hướng đầu ra sang một tệp và sau đó đến bàn điều khiển:

dir > a.txt | type a.txt

Trong đó dir là lệnh mà đầu ra cần được chuyển hướng, a.txt một tệp nơi lưu trữ đầu ra.


100
Điều này thỏa mãn câu trả lời, nhưng xuất ra dữ liệu sau khi lệnh dir hoàn thành thay vì dữ liệu được tạo ra.
Leigh Riffel

10
nó sẽ hoạt động, nhưng bạn sẽ bị kẹt nếu lệnh chờ đầu vào từ stdin.
Vitim.us

5
Tôi thích câu trả lời đơn giản này! Tôi thấy rằng &thay vì một |là cần thiết cho đầu ra của một số lệnh, như pinghoặc7z.exe
Wes Larson

Không làm việc cho các lệnh tương tác thay vì dir. Ví dụ : chkdsk /f c: > c:\Temp.txt | c:\Temp.txt. Các tập tin báo cáo hệ thống bị khóa bởi một quá trình khác.
Sopalajo de Arrierez

4
@lii re: handle output to stderr- Thêm 2>&1chuyển hướng để nó giống như thế này: dir 2>&1 > a.txt & type a.txtvà bạn nên có stderr trộn với thiết bị xuất chuẩn.
Jesse Chisholm

97

Có một cổng Win32 của teelệnh Unix , thực hiện chính xác điều đó. Xem http://unxutils.sourceforge.net/ hoặc http://getgnuwin32.sourceforge.net/


17
Liên kết trỏ đến một triển khai Windows của tee lệnh Unix, vì vậy nó hoạt động trên Windows.
Brian Rasmussen

3
Vâng, bỏ phiếu lên câu trả lời và bình luận. Tôi thực sự thích CygWin vì nó có mọi thứ nhưng một số người thích các công cụ không phải DLL mà họ có thể chọn và chọn.
paxdiablo

3
Rất nhiều tiện ích Unix cũng được dự án GnuWin32 chuyển đến, xem gnuwin32.sourceforge.net .
VladV

2
UnxUtils được cập nhật lần cuối vào năm 2003; GnuWin32 cập nhật hơn một chút.
quack quixote

9
Nếu bạn, giống như tôi, vật lộn để tìm teegói của GnuWin32 , bạn sẽ tìm thấy nó trong gnuwin32.sourceforge.net/packages/coreutils.htmlm .
Nigel Touch

49

Kiểm tra này: wintee

Không cần cygwin.

Tôi đã gặp và báo cáo một số vấn đề mặc dù.

Ngoài ra, bạn có thể kiểm tra unxutils vì nó có chứa tee (và không cần cygwin), nhưng hãy cẩn thận khi xuất EOL giống như UNIX ở đây.

Cuối cùng, nhưng không kém phần quan trọng, là nếu bạn có PowerShell, bạn có thể thử Tee-Object. Nhập get-help tee-objectvào bảng điều khiển PowerShell để biết thêm.


4
Tại sao bỏ phiếu xuống? 95% trả lời ở đây có một điểm chung: đầu ra chỉ được chuyển hướng sau khi lệnh ban đầu kết thúc: đọc các bình luận. Tiện ích UNIX teeđầu ra thời gian thực. wteecó chức năng tương tự. Nếu bạn không quan tâm đến các lỗi, nó sẽ làm tốt thôi.
Davor Josipovic

Đó là giải pháp duy nhất hiệu quả với tôi, không có Powershell> 4.0. Đồng ý
Alex

46

@ tori3852

Tôi thấy rằng

dir > a.txt | type a.txt

không hoạt động (chỉ một vài dòng đầu tiên của danh sách dir - nghi ngờ một số loại quy trình giả mạo và phần thứ hai, lệnh 'loại' đã chấm dứt trước khi danh sách thảm khốc hoàn thành?), vì vậy thay vào đó tôi đã sử dụng:

dir > z.txt && type z.txt

đã làm - các lệnh tuần tự, một lệnh hoàn thành trước khi bắt đầu thứ hai.


17
Bạn nên sử dụng &thay vì &&nếu bạn muốn đảm bảo typelệnh được thực thi ngay cả khi dirlệnh thất bại. Điều này hữu ích khi có một số dạng lỗi trong lệnh của bạn và bạn vẫn muốn xem tệp nhật ký trên bàn điều khiển. Xem bài viết của Microsoft về điều này . Tuy nhiên, điều này có vấn đề %errorlevel%được đặt thành mức lỗi type(sẽ là 0).
ADTC

25

Thật không may, không có điều đó.

Các ứng dụng giao diện điều khiển Windows chỉ có một tay cầm đầu ra duy nhất. (Chà, có hai cái STDOUT, STDERRnhưng nó không thành vấn đề ở đây) >Chuyển hướng đầu ra thường được ghi vào tay cầm bàn điều khiển để xử lý tệp.

Nếu bạn muốn có một số loại ghép kênh, bạn phải sử dụng một ứng dụng bên ngoài mà bạn có thể chuyển hướng đầu ra. Ứng dụng này sau đó có thể ghi vào một tệp và vào bàn điều khiển một lần nữa.


3
teetrên * nix cũng là một ứng dụng riêng biệt, không phải là một số chuyển hướng trên vỏ
phuclv

22

Một ứng dụng bảng điều khiển C # đơn giản sẽ thực hiện thủ thuật:

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());
        }
    }
}

Để sử dụng điều này, bạn chỉ cần đưa lệnh nguồn vào chương trình và cung cấp đường dẫn của bất kỳ tệp nào bạn muốn sao chép đầu ra. Ví dụ:

dir | CopyToFiles files1.txt files2.txt 

Sẽ hiển thị kết quả của dir cũng như lưu trữ kết quả trong cả files1.txt và files2.txt.

Lưu ý rằng không có nhiều (bất cứ điều gì!) Trong cách xử lý lỗi ở trên và việc hỗ trợ nhiều tệp có thể không thực sự được yêu cầu.


5
Hmm, tải tee / cygwin không có gì hoặc mua MSVS bằng tiền mặt kiếm được của tôi cho một chương trình nhỏ bé như vậy? Đó là một khó khăn :-)
paxdiablo

19
Bạn không cần studio trực quan để biên dịch rằng, các công cụ dòng lệnh thực sự miễn phí. chỉ cần google ".net sdk download" cho liên kết (liên kết trực tiếp dường như thay đổi xung quanh nhưng google dường như luôn hoạt động).
Kris

13
Visual Studio Express cũng miễn phí, nhưng tôi vẫn sẽ chỉ sử dụng tee cho việc này.
Brian Rasmussen

7
Cygwin là một nỗi đau để cài đặt. Upvote cho bạn bởi vì đây là những gì tôi đang tìm kiếm.
Samaursa

1
Tôi không nghĩ rằng kết quả này cho bảng điều khiển và các tệp cùng một lúc phải không?
mjaggard

20

Điều này hoạt động, mặc dù nó hơi xấu:

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

Nó linh hoạt hơn một chút so với một số giải pháp khác, ở chỗ nó hoạt động theo từng câu lệnh để bạn cũng có thể sử dụng nó để nối thêm. Tôi sử dụng điều này khá nhiều trong các tệp bó để ghi nhật ký và hiển thị thông báo:

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

Có, bạn chỉ có thể lặp lại câu lệnh ECHO (một lần cho màn hình và lần thứ hai chuyển hướng đến logfile), nhưng điều đó có vẻ tệ và là một vấn đề bảo trì. Ít nhất theo cách này, bạn không phải thay đổi tin nhắn ở hai nơi.

Lưu ý rằng _ chỉ là một tên tệp ngắn, vì vậy bạn sẽ cần đảm bảo xóa nó ở cuối tệp bó của mình (nếu bạn đang sử dụng tệp bó).


2
Điều đó chỉ hữu ích nếu bạn muốn hiển thị nội dung SAU quy trình của bạn đã chạy. Và đó không phải là một vấn đề khó giải quyết.
Christopher Họa sĩ

1
Vâng, tôi đoán điều này giải quyết một vấn đề hơi khác so với những gì người đăng ban đầu đang hỏi.
MTS

1
+1 Đây là cách tôi luôn thực hiện. Tôi tin rằng đây là câu trả lời chính xác cho câu hỏi ban đầu và nên được đánh dấu là như vậy. Thủ thuật, như @MTS gợi ý, là bạn thực sự ghi vào hai tệp: một tệp được tạo cho mỗi lệnh / dòng (do đó một ">" sẽ ghi đè lên mỗi lần), sau đó bạn nhập dòng đó vào màn hình (sau đó bạn nhập dòng đó vào màn hình ( loại ) và cuối cùng, bạn nhập lại và chuyển hướng đầu ra của nó, tất cả các PHỤ LỤC dài, đến tệp nhật ký của bạn với ">>". Đây là cách tôi đã thực hiện trong nhiều năm, mặc dù tôi thích tệp tạm thời " " đơn giản . Tôi đã luôn luôn thực hiện "tmp.txt" hoặc soemthing. Vâng, xóa nó sau đó.
eduncan911

Đây là một cách tiếp cận tốt nhưng tôi gặp vấn đề với một số lỗi không được ghi lại. Tuy nhiên, việc đặt các typelệnh trên các dòng riêng biệt (trong chương trình con) đã cố định.
Nate Cook

Chỉ cần những gì tôi cần cho ứng dụng của tôi.
Alan

16

mtee là một tiện ích nhỏ hoạt động rất tốt cho mục đích này. Nó miễn phí, nguồn mở và nó chỉ hoạt động.

Bạn có thể tìm thấy nó tại http://www.commandline.co.uk .

Được sử dụng trong một tệp bó để hiển thị đầu ra VÀ tạo một tệp nhật ký đồng thời, cú pháp trông như thế này:

    someprocess | mtee /+ mylogfile.txt

Trong đó / + có nghĩa là nối thêm đầu ra.

Điều này giả định rằng bạn đã sao chép mtee vào một thư mục trong PATH, tất nhiên.


1
Điều này dường như chờ cho đến khi đầu ra hoàn thành cũng trước khi xuất ra tệp hoặc bàn điều khiển.
mellamokb

14

Tôi muốn mở rộng một chút về câu trả lời tuyệt vời của Saxon Druce .

Như đã nêu, bạn có thể chuyển hướng đầu ra của một tệp thực thi trong thư mục hiện tại như sau:

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

Tuy nhiên, điều này chỉ đăng nhập stdoutvào test.txt. Nó cũng không đăng nhập stderr.

Giải pháp rõ ràng là sử dụng một cái gì đó như thế này:

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

Tuy nhiên, điều này sẽ không làm việc cho tất cả các something.exes. Một số something.exes sẽ giải thích 2>&1như là một đối số và thất bại. Giải pháp chính xác là thay vào đó chỉ có dấu nháy đơn xung quanh something.exevà các công tắc và đối số của nó, như vậy:

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

Tôi đã thử điều này khi xây dựng pyqt5.7 trên windows 10, nó khá chậm chạp, đầu ra giao diện điều khiển không phải là thời gian thực, có lẽ nó được đệm? tệp nhật ký có vẻ đúng mặc dù
Shuman

3
Tất cả điều đó là hoàn toàn sai. Nó hoàn toàn không hoạt động đối với tôi. Lệnh cuối cùng 'tee' is not recognized as an internal or external commandcho lý do rõ ràng. Với 2>&1dòng cmd bên trong, bất kỳ đầu ra nào đến stderr đều gây ra lỗi từ powershell.
Pavel P

Có thể là một tham chiếu đến lệnh ghép ngắn PowerShell Tee-Object - technet.microsoft.com/en-us/l Library / ee177014.aspx
Bernd

9

Tôi đồng ý với Brian Rasmussen, cổng unxutils là cách dễ nhất để làm điều này. Trong phần Batch Files trong các trang Scripting của mình, Rob van der Woude cung cấp nhiều thông tin về việc sử dụng các lệnh MS-DOS và CMD. Tôi nghĩ rằng anh ta có thể có một giải pháp tự nhiên cho vấn đề của bạn và sau khi đào bới xung quanh đó, tôi đã tìm thấy TEE.BAT , có vẻ như đó là một triển khai ngôn ngữ hàng loạt MS-DOS của tee. Đây là một tệp bó trông khá phức tạp và thiên hướng của tôi vẫn là sử dụng cổng unxutils.


Điều đó tee.bat trông tốt đẹp. Hy vọng OP kiểm tra điều này.
Jay

10
Lưu ý rằng việc sử dụng TEE.BAT sẽ xuất ra sau khi lệnh hoàn thành, giống như ví dụ "dir> a.txt | gõ a.txt" được đăng gần đó.
adzm

8

Nếu bạn có cygwin trong đường dẫn môi trường windows, bạn có thể sử dụng:

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

7
Nếu bạn sẽ sử dụng Cygwin, nó đi kèm với tee.
Ông Llama

7

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

Điều này sẽ giúp chuyển hướng cả STDOUT và STDERR


Điều này không hoạt động. Tôi đã thử sử dụng cái này để khởi chạy JBoss run.bat và nó bị nghẹt trong khi khởi động và máy chủ đóng băng. Có vấn đề với phương pháp này ...
djangofan

@raja ashok, không làm việc cho tôi. Tôi đã thử python.exe 1> file.txt 2> & 1 | gõ file.txt
neo

4

Tôi biết đây là một chủ đề rất cũ, nhưng trong các câu trả lời trước đây không có triển khai đầy đủ về một Tee thời gian thực được viết bằng Batch. Giải pháp của tôi dưới đây là tập lệnh lai Batch-JScript sử dụng phần JScript chỉ để lấy đầu ra từ lệnh piped, nhưng việc xử lý dữ liệu được thực hiện trong phần Batch. Cách tiếp cận này có lợi thế là bất kỳ lập trình viên Batch nào cũng có thể sửa đổi chương trình này để phù hợp với nhu cầu cụ thể. Chương trình này cũng xử lý chính xác đầu ra của lệnh CLS được tạo bởi các tệp Batch khác, nghĩa là, nó sẽ xóa màn hình khi phát hiện ra lệnh 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");

Bất kỳ cách này có thể nắm bắt đầu ra stderr? Tôi có một exe khó chịu xuất ra mọi thứ trên luồng lỗi tiêu chuẩn (nghĩa là để xuất ra một tệp thông thường bạn sẽ làmfile.exe 2>output.txt
Đánh dấu

Tôi đã hiểu rồi. Bạn có thể làm điều đó bằng cách file.exe 2>&1|tee.battìm thấy ở đây: superuser.com/questions/452763/ mẹo
Mark Deven

4

Tôi cũng đang tìm kiếm giải pháp tương tự, sau một chút cố gắng, tôi đã thành công có thể đạt được điều đó trong Command Prompt. Đây là giải pháp của tôi:

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

Nó thậm chí còn nắm bắt bất kỳ lệnh PAUSE nào.


3

Đây là một ví dụ về những gì tôi đã sử dụng dựa trên một trong những câu trả lời khác

@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

Một cái gì đó như thế này nên làm những gì bạn cần?

%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

Hầu như, nhưng nó không hiển thị đồng thời - nếu bạn có một nhiệm vụ chạy dài, bạn sẽ không nhận được kết quả trong thời gian dài.
JustAMartin

3

gửi đầu ra đến bàn điều khiển, nối vào nhật ký bàn điều khiển, xóa đầu ra khỏi lệnh hiện tại

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

8
quan tâm để giải thích những gì đang xảy ra ở đây?
John Demetriou

2

Đây là một biến thể của câu trả lời trước của MTS, tuy nhiên, nó bổ sung một số chức năng có thể hữu ích cho những người khác. Đây là phương pháp mà tôi đã sử dụng:

  • Một lệnh được đặt dưới dạng một biến, có thể được sử dụng sau này trong toàn bộ mã, để xuất ra cửa sổ lệnh và nối vào tệp nhật ký, sử dụng set _Temp_Msg_Cmd=
    • lệnh đã thoát khỏi chuyển hướng bằng cách sử dụng ^ký tự cà rốt để các lệnh không được đánh giá ban đầu
  • Một tệp tạm thời được tạo với tên tệp tương tự như tệp bó đang được gọi %~n0_temp.txtcó sử dụng cú pháp mở rộng tham số dòng lệnh %~n0 để lấy tên của tệp bó.
  • Đầu ra được nối vào một tệp nhật ký riêng %~n0_log.txt

Đây là chuỗi các lệnh:

  1. Các thông báo đầu ra và lỗi được gửi đến tệp tạm thời ^> %~n0_temp.txt 2^>^&1
  2. Nội dung của tệp tạm thời là cả hai:
    • gắn vào logfile ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • xuất ra cửa sổ lệnh ^& type %~n0_temp.txt
  3. Các tập tin tạm thời với tin nhắn sẽ bị xóa ^& del /Q /F %~n0_temp.txt

Dưới đây là ví dụ:

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

Bằng cách này, lệnh đơn giản có thể được thêm vào sau các lệnh sau trong tệp bó trông sạch hơn rất nhiều:

echo test message %_Temp_Msg_Cmd%

Điều này có thể được thêm vào cuối các lệnh khác. Theo như tôi có thể nói nó sẽ hoạt động khi tin nhắn có nhiều dòng. Ví dụ: lệnh sau xuất ra hai dòng nếu có thông báo lỗi:

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

Điều này sẽ tạo một tệp nhật ký với datetime hiện tại và bạn có thể các dòng bàn điều khiển trong quá trình


11
không phải bạn gọi cùng một chương trình hai lần với điều này sao?
elcool

1

Tôi sử dụng một chương trình con hàng loạt với câu lệnh "for" để nhận lệnh xuất một dòng tại một thời điểm và cả hai ghi dòng đó vào một tệp và xuất nó ra bàn điều khiển.

@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

Tôi cũng làm như vậy khi cố gắng bắt đầu ra từ một lệnh (IE đặt nó vào trong) nhưng sau đó tôi chỉ gọi hàm con tiêu chuẩn của mình để lặp lại màn hình và ghi vào nhật ký vì tôi sử dụng nó trong toàn bộ tập lệnh của mình thay vì sử dụng echo . Không chắc tại sao điều đó lại bị downvote từ người khác nên tôi đã nâng cấp nó.
Ben Personick

1

Nếu bạn đang sử dụng CLI, tại sao không sử dụng vòng lặp FOR để "LÀM" bất cứ điều gì bạn muốn:

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

Tài nguyên tuyệt vời trên Windows CMD cho các vòng lặp: https://ss64.com/nt/for_cmd.html Chìa khóa ở đây là thiết lập các vạch đo (độ trễ), sẽ chia nhỏ từng dòng đầu ra, thành không có gì. Bằng cách này, nó sẽ không phá vỡ mặc định của khoảng trắng. % A là một chữ cái tùy ý, nhưng nó được sử dụng trong phần "làm" để ... làm gì đó với các ký tự được phân tích cú pháp ở mỗi dòng. Trong trường hợp này, chúng ta có thể sử dụng ký hiệu (&&) để thực thi lệnh echo thứ 2 để tạo hoặc nối thêm (>>) vào một tệp mà chúng ta chọn. An toàn hơn để giữ thứ tự các lệnh DO này trong trường hợp có vấn đề khi ghi tệp, ít nhất chúng ta sẽ nhận được tiếng vang đến bàn điều khiển trước. Dấu hiệu (@) phía trước tiếng vang đầu tiên ngăn không cho bảng điều khiển hiển thị lệnh echo và thay vào đó chỉ hiển thị kết quả của lệnh hiển thị các ký tự theo% a. Nếu không, bạn sẽ thấy:

echo Volume trong ổ đĩa [x] là Windows
Volume trong ổ đĩa [x] là Windows

CẬP NHẬT: / F bỏ qua các dòng trống và chỉ khắc phục là lọc trước đầu ra thêm một ký tự cho mỗi dòng (có thể với các số dòng thông qua lệnh tìm). Giải quyết vấn đề này trong CLI không nhanh hay đẹp. Ngoài ra, tôi cũng không bao gồm STDERR, vì vậy, đây cũng là lỗi bắt lỗi:

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

Chuyển hướng thông báo lỗi

Các dấu mũ (^) ở đó để thoát khỏi các ký hiệu sau chúng, bởi vì lệnh là một chuỗi đang được giải thích, trái ngược với việc nói, nhập trực tiếp vào dòng lệnh.


1

Cũng giống như unix.

dir | tee a.txt

Không hoạt động Trên windows XP, nó yêu cầu mksntcài đặt.

Nó hiển thị trên dấu nhắc cũng như nối vào tệp.


0

Theo dõi giúp nếu bạn muốn một cái gì đó thực sự nhìn thấy trên màn hình - ngay cả khi tệp bó được chuyển hướng đến một tệp. Thiết bị CON cũng có thể được sử dụng nếu được chuyển hướng đến một tệp

Thí dụ:

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

Đồng thời xem mô tả chuyển hướng tốt: http://www.p-dd.com/ch CHƯƠNG7-page14.html


0

Làm cách nào để hiển thị và chuyển hướng đầu ra thành một tệp. Giả sử nếu tôi sử dụng lệnh dos, dir> test.txt, lệnh này sẽ chuyển hướng đầu ra sang tệp test.txt mà không hiển thị kết quả. Cách viết lệnh để hiển thị đầu ra và chuyển hướng đầu ra sang tệp bằng DOS, tức là dấu nhắc lệnh windows, không phải trong UNIX / LINUX.

Bạn có thể thấy các lệnh này trong biterscripting ( http://www.biterscripting.com ) hữu ích.

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

Điều này hoạt động trong thời gian thực nhưng cũng là một loại xấu xí và hiệu suất chậm. Cũng không được kiểm tra tốt:

@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
Không, đó không phải là thời gian thực, nó đợi cho đến khi %MYCOMMAND%kết thúc và nó thất bại trong nhiều trường hợp. Nó bỏ qua dòng sản phẩm nào, các dòng bắt đầu với ;thất bại với nội dung như <space>/<TAB>, ON, OFFhoặc /?. Nhưng phần còn lại đôi khi có thể hoạt động :-)
jeb

0

Một cách khác là để stdout tee stderr trong chương trình của bạn:

trong java:

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

Sau đó, trong batchfile dos của bạn: java program > log.txt

Thiết bị xuất chuẩn sẽ đi đến logfile và thiết bị xuất chuẩn (cùng dữ liệu) sẽ hiển thị trên bảng điều khiển.


0

Tôi cài đặt perl trên hầu hết các máy của mình để có câu trả lời bằng 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;

thư mục | perl tee.pl hoặc dir | perl tee.pl dir.bat

thô và chưa được kiểm tra.


0

Một biến thể khác là tách đường ống, sau đó chuyển hướng đầu ra theo ý muốn.

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

Lưu ở trên vào một tập tin .bat. Nó cũng phân tách đầu ra văn bản trên filestream 1 thành filestream 3, mà bạn có thể chuyển hướng khi cần. Trong các ví dụ của tôi dưới đây, tôi đã gọi đoạn script trên là 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. Nhấp vào liên kết cho "setup-x86_.exe"
  3. Chạy trình cài đặt
  4. Trên trang ~ 2, chọn "nhân bản" để tải xuống (Tôi đã tìm tên miền .edu)
  5. Tôi nói ok với các tùy chọn tiêu chuẩn
  6. Cygwin nhanh chóng hoàn tất cài đặt
  7. Mở cmd
  8. Nhập c:\cygwin64\bin\script.exevà nhập
  9. Nhập cmdvà nhập
  10. Chạy chương trình của bạn
  11. Kiểu exit và nhập (thoát cmd.exe của Cygwin)
  12. Nhập exitvà nhập (thoát khỏi script.exe của Cygwin)
  13. Xem đầu ra màn hình của chương trình của bạn trong tệp văn bản có tên là "typecript"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.