例如:
c:\Windows>dir > windows-dir.txt
有没有办法让dir
的输出既显示在控制台窗口中,又将其放入文本文件中?
c:\Windows>dir > windows-dir.txt
有没有办法让dir
的输出既显示在控制台窗口中,又将其放入文本文件中?
不能通过纯重定向实现,但是可以使用一些技巧(如tee.bat)来实现。
我尝试解释一下重定向。
使用> 文件名或< 文件名将其中一个十个流重定向到文件中。
无论重定向是在命令之前还是之后都不重要,因此这两行代码几乎相同。
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中,而stream3将进入nothing.txt(DIR不使用流3)。
Stream0是STDIN,
Stream1是STDOUT,
Stream2是STDERR,
Stream3-9未使用。
但是,如果您尝试多次重定向相同的流会发生什么呢?dir > files.txt > two.txt
"只能有一个",它总是最后一个!
所以它等同于 dir > two.txt
好的,还有一种额外的可能性,将一个流重定向到另一个流。
dir 1>files.txt 2>&1
2>&1将stream2重定向到stream1,1>files.txt将所有内容重定向到files.txt。
这里的顺序很重要!
dir ... 1>nul 2>&1
dir ... 2>&1 1>nul
两者不同。第一行将所有输出(STDOUT和STDERR)重定向到NUL,
但第二行将STDOUT重定向到NUL,将STDERR重定向到“空”STDOUT。
一个结论是,很明显为什么Otávio Décio和andynormancx的示例无法工作。
command > file >&1
dir > file.txt >&2
两者都试图重定向stream1两次,但是“只能有一个”,并且它始终是最后一个。
所以你得到
command 1>&1
dir 1>&2
在第一个示例中,将流stream1重定向到自身是不允许的(也没有多大用处)。
3<&2
(注意是LT而不是GT),然后是3>errors.txt
。但这样做的结果很糟糕 - 所有随后的stderr输出都被捕获到了errors.txt
中(也就是说,来自其他命令的输出也被捕获了!)。 - Tomasz Gandorfor /f "delims=" %%v in ('dir') do echo %%v>>file.txt
。 - amegyoushi只需使用Windows版本的UNIX tee命令(从http://unxutils.sourceforge.net获取),方法如下:
mycommand > tee outpu_file.txt
如果你还需要 STDERR 输出,那么请使用以下命令。2>&1
会将 STDERR 输出与 STDOUT(主要流)合并。mycommand 2>&1 | tee output_file.txt
1>tee a.txt
会将stdout重定向到一个名为tee
而不是调用tee
命令的文件。有人可以确认这个答案对他们有效吗? - mafutype 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
。然而,如果需要实时输出,则可以使用例如 tee 工具的 Windows 版本来实现… - mousio是的,有一种方法可以在控制台(屏幕)和文件中显示单个命令的输出。使用您的示例,使用...
@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
delims=
。 - amegyoushi我的建议是:
创建一个子程序,接收消息并自动将其发送到控制台和日志文件。
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
如果您在消息中添加一个变量,请确保在将其发送到子例程之前删除其中的引号,否则它可能会破坏您的批处理。当然,这仅适用于回显。
setlocal enabledelayedexpansion
而不是只用 setlocal
2) 在子程序中,我使用延迟扩展来处理日志文件变量,所以用 >> !logfile!
代替 >> %logfile%
。这样,在代码块内(比如在 if 语句内)调用时就能正常工作。3) 我删除了 "set message" 行,因为没有必要再创建一个额外的变量。我们已经有 $~1
中的内容了,所以我将两个 echo 命令都改成了 echo $~1
。 - Nate如果您想追加而不是替换输出文件,则可以使用
dir 1>> files.txt 2>> err.txt
或者
dir 1>> files.txt 2>>&1
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/iamshiao/Tee
command > file >&1