如何在 bat 脚本中回显和发送控制台输出到文件?

我有一个批处理脚本,它执行一个任务并将输出发送到一个文本文件。是否有一种方法可以在控制台窗口上显示输出?

例如:

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

是否有一种方法可以将 dir的输出显示在控制台窗口中,并将其放入文本文件中?

399619 次浏览
command > file >&1

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

type windows-dir.txt

在那条线之后。

对我有效的解决方案是: Dir > a.txt | type a.txt

不,单纯的重定向是不行的。
但是通过一些技巧(如 Tee Bat)你可以。

我试着解释一下重定向。

使用 > 档案< file重定向十个流中的一个
如果重定向在命令之前或之后, 所以这两条线几乎是一样的。

dir > file.txt
> file.txt dir

本例中的重定向只是 1 >的快捷方式,这意味着流1(STDOUT)将被重定向。
因此,您可以重定向任何流与前缀的数字,如 2 > err.txt,它也被允许重定向多个流在一行。

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

在本例中,“标准输出”将进入 files.txt,所有错误将进入 err.txt,stream 3将进入 nothing.txt (DIR 不使用流3)。
Stream0是 STDIN
Stream1是 STDOUT
Stream2是 STDERR
Stream3-9不使用

但是,如果尝试多次重定向相同的流,会发生什么情况呢?

dir > files.txt > two.txt

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

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

dir 1>files.txt 2>&1

2 & 1 将 stream 2重定向到 stream 1,而 1 > 文件将所有元素重定向到 Files.txt
命令在这里很重要!

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

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

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

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

它们都尝试重定向 stream 1两次,但是“ There can be only one”,而且总是最后一次。
所以你得到了

command 1>&1
dir 1>&2

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

希望能有帮助。

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

mycommand > tee outpu_file.txt

如果还需要 STDERR 输出,请使用以下命令。
2>&1将 STDERR 输出合并到 STDOUT (主流)中。

mycommand 2>&1 | tee output_file.txt

我喜欢 atn 的回答,但是它并不像 Wintee那样容易下载,Wintee也是开源的,只提供 tee 功能(如果您只想要 tee 而不是整套 unix 实用程序,那么它很有用)。我是从 davor 对 显示命令提示符输出并将其重定向到一个文件的回答中了解到这一点的,在这里您还可以找到关于 unix 实用程序的参考。

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

@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
)

如果有时只想在控制台(屏幕)上输出,其他时间只发送到文件,其他时间同时发送到两个文件,那么使用一个变量指定 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

“ Tomas R”提供的解决方案完美地解决了 OP 的问题,并且本地化了。

试试: Chkdsk c: > output.txt | type output.txt

这个命令的输出包含一个完成百分比,该百分比将连续输出到文件中,因此它看起来有点凌乱(即文本将随着它的进展而附加)。这种情况不会发生在输出到 STDOUT (屏幕)的位上。如果只执行相同的命令而没有重定向,那么情况就是这样。

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

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

或者

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

我的选择是:

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

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

如果您向消息中添加了一个变量,请务必在将其发送到子例程之前删除其中的引号,否则它可能会扰乱您的批处理。 当然,这只适用于附和。

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

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

批处理文件的用法与使用 Unixtee的用法相同

foo | tee xxx.log

这是一个包含 Tee.exe 的存储库,如果你没有工具可以编译的话 Https://github.com/iamshiao/tee

我觉得你想要这样的东西:

echo Your Msg> YourTxtFile.txt

或者你想要一句新台词:

echo Your Msg>> YourTxtFile.txt

这些命令对于日志非常有用。

注意: 这有时会出现故障,并替换我电脑上的整个文本文件。

另一个注意: 如果该文件不存在,它将创建该文件。