windows 如何回显并将控制台输出发送到 bat 脚本中的文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/503846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:00:54  来源:igfitidea点击:

How do I echo and send console output to a file in a bat script?

windowsbatch-filecmd

提问by JamesEggers

I have a batch script that executes a task and sends the output to a text file. Is there a way to have the output show on the console window as well?

我有一个执行任务并将输出发送到文本文件的批处理脚本。有没有办法让输出显示在控制台窗口上?

For Example:

例如:

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

Is there a way to have the output of dirdisplay in the console window as well as put it into the text file?

有没有办法dir在控制台窗口中显示输出并将其放入文本文件中?

回答by jeb

No, you can't with pure redirection.
But with some tricks (like tee.bat) you can.

不,您不能使用纯重定向。
但是通过一些技巧(比如tee.bat)你可以。

I try to explain the redirection a bit.

我试着解释一下重定向。

You redirect one of the ten streams with > fileor < file
It is unimportant, if the redirection is before or after the command, so these two lines are nearly the same.

你用> file< file重定向十个流之一
并不重要,如果重定向在命令之前或之后,那么这两行几乎相同。

dir > file.txt
> file.txt dir

The redirection in this example is only a shortcut for 1>, this means the stream 1 (STDOUT) will be redirected.
So you can redirect any stream with prepending the number like 2> err.txtand it is also allowed to redirect multiple streams in one line.

本例中的重定向只是1>的快捷方式,这意味着流 1 (STDOUT) 将被重定向。
因此,您可以重定向任何流,并在前面加上2> err.txt 之类的数字,并且还允许在一行中重定向多个流。

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

In this example the "standard output" will go into files.txt, all errors will be in err.txt and the stream3 will go into nothing.txt (DIR doesn't use the stream 3).
Stream0 is STDIN
Stream1 is STDOUT
Stream2 is STDERR
Stream3-9 are not used

在这个例子中,“标准输出”将进入 files.txt,所有错误都将在 err.txt 中,而 stream3 将进入 nothing.txt(DIR 不使用流 3)。
Stream0 为 STDIN
Stream1 为 STDOUT Stream2
为 STDERR
Stream3-9 未使用

But what happens if you try to redirect the same stream multiple times?

但是如果您尝试多次重定向同一个流会发生什么?

dir > files.txt > two.txt

"There can be only one", and it is always the last one!
So it is equal to dir > two.txt

“只能有一个”,而且永远是最后一个!
所以它等于dir > two.txt

Ok, there is one extra possibility, redirecting a stream to another stream.

好的,还有一种额外的可能性,将一个流重定向到另一个流。

dir 1>files.txt 2>&1 

2>&1redirects stream2 to stream1 and 1>files.txtredirects all to files.txt.
The order is important here!

2>&1将 stream2 重定向到 stream1 ,1>files.txt将所有重定向到files.txt
顺序在这里很重要!

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

are different. The first one redirects all (STDOUT and STDERR) to NUL,
but the second line redirects the STDOUT to NUL and STDERR to the "empty" STDOUT.

是不同的。第一个将所有(STDOUT 和 STDERR)重定向到 NUL,
但第二行将 STDOUT 重定向到 NUL,将 STDERR 重定向到“空”STDOUT。

As one conclusion, it is obvious why the examples of Otávio Décio and andynormancx can't work.

作为一个结论,很明显为什么 Otávio Décio 和 andynormancx 的例子不起作用。

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

Both try to redirect stream1 two times, but "There can be only one", and it's always the last one.
So you get

两者都尝试重定向 stream1 两次,但“只能有一个”,而且总是最后一个。
所以你得到

command 1>&1
dir 1>&2

And in the first sample redirecting of stream1 to stream1 is not allowed (and not very useful).

并且在第一个示例中,不允许将流 1 重定向到流 1(并且不是很有用)。

Hope it helps.

希望能帮助到你。

回答by atn

Just use the Windows version of the UNIX tee command (found from http://unxutils.sourceforge.net) in this way:

只需以这种方式使用 Windows 版本的 UNIX tee 命令(可从http://unxutils.sourceforge.net 找到):

mycommand > tee outpu_file.txt

If you also need the STDERR output, then use the following.
The 2>&1combines the STDERR output into STDOUT (the primary stream).

如果您还需要 STDERR 输出,请使用以下内容。
2>&1结合了stderr输出到STDOUT(一次流)。

mycommand 2>&1 | tee output_file.txt

回答by Mark Pim

If you don't need the output in real time (i.e. as the program is writing it) you could add

如果您不需要实时输出(即在程序编写时),您可以添加

type windows-dir.txt

after that line.

在那条线之后。

回答by NSPKUWCExi2pr8wVoGNk

The solution that worked for me was: dir > a.txt | type a.txt.

对我有用的解决方案是:dir > a.txt | 输入 a.txt

回答by Amazinate

Yes, there is a way to show a single command output on the console (screen) and in a file. Using your example, use...

是的,有一种方法可以在控制台(屏幕)和文件中显示单个命令输出。使用您的示例,使用...

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

Detailed explanation:

详细解释:

The FORcommand parses the output of a command or text into a variable, which can be referenced multiple times.

FOR命令将命令或文本的输出解析为一个变量,该变量可以被多次引用。

For a command, such as DIR /B, enclose in single quotes as shown in example below. Replace the DIR /Btext with your desired command.

对于命令,例如DIR /B,用单引号括起来,如下例所示。DIR /B用您想要的命令替换文本。

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

For displaying text, enclose text in double quotes as shown in example below.

要显示文本,请将文本括在双引号中,如下例所示。

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

... And with line wrapping...

......还有换行......

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

If you have times when you want the output only on console (screen), and other times sent only to file, and other times sent to both, specify the "DO" clause of the FOR loop using a variable, as shown below with %TOECHOWHERE%.

如果您有时只希望在控制台(屏幕)上输出,而有时只希望将输出发送到文件,而有时又希望将输出发送到两者,请使用变量指定 FOR 循环的“DO”子句,如下所示使用%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

回答by Otávio Décio

command > file >&1

回答by Jochen

If you want to append instead of replace the output file, you may want to use

如果要追加而不是替换输出文件,则可能需要使用

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

or

或者

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

回答by JPZ

My option was this:

我的选择是这样的:

Create a subroutine that takes in the message and automates the process of sending it to both console and log file.

创建一个接收消息并自动将其发送到控制台和日志文件的子程序。

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

If you add a variable to the message, be sure to remove the quotes in it before sending it to the subroutine or it can screw your batch. Of course this only works for echoing.

如果您向消息中添加变量,请确保在将其发送到子程序之前删除其中的引号,否则它可能会破坏您的批处理。当然,这只适用于回声。

回答by Circle Hsiao

I made a simple C# console which can handle real-time output to both cmd screen and log

我制作了一个简单的 C# 控制台,它可以处理 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;
    }
}

The batch file usage is the same as how you use Unix tee

批处理文件的使用方式与您使用 Unix 的方式相同 tee

foo | tee xxx.log

And here is the repository which includes the Tee.exe in case you don't have tool to compile https://github.com/iamshiao/Tee

这是包含 Tee.exe 的存储库,以防您没有编译工具 https://github.com/iamshiao/Tee

回答by sage

I like atn's answer, but it was not as trivial for me to download as wintee, which is also open source and only gives the tee functionality (useful if you just want tee and not the entire set of unix utilities). I learned about this from davor's answer to Displaying Windows command prompt output and redirecting it to a file, where you also find reference to the unix utilities.

我喜欢ATN的答案,但它并不像平凡的我下载的wintee,这也是开源的,只给出了发球功能(有用的,如果你只是想发球,而不是整个的UNIX实用工具的)。我从 davor 对Displaying Windows command prompt output and redirecting it to a file的回答中了解到这一点,您还可以在其中找到对 unix 实用程序的引用。