如何在Windows命令提示符中运行命令行应用程序,同时显示输出并将输出重定向到文件?
例如,如果我要运行命令dir > test.txt,这将把输出重定向到一个名为test.txt的文件,而不显示结果。
我如何写一个命令来显示输出并将输出重定向到Windows命令提示符中的文件,类似于Unix上的tee命令?
如何在Windows命令提示符中运行命令行应用程序,同时显示输出并将输出重定向到文件?
例如,如果我要运行命令dir > test.txt,这将把输出重定向到一个名为test.txt的文件,而不显示结果。
我如何写一个命令来显示输出并将输出重定向到Windows命令提示符中的文件,类似于Unix上的tee命令?
当前回答
我使用带有“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
其他回答
这是实时工作,但也是一种丑陋和性能缓慢。也没有经过很好的测试:
@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
这不是另一个答案,更多的是对已经存在的答案的概述和澄清 显示Windows命令提示符输出并将其重定向到文件 和其他人
我自己发现,有一系列问题使得一组tee实现在Windows中不可靠(在我的情况下是Windows 7)。
我需要特别使用tee实现,因为已经使用了自重定向的批处理脚本:
@echo off
setlocal
... some conditions here ..
rem the redirection
"%COMSPEC%" /C call %0 %* 2>&1 | "<path_to_tee_utililty>" ".log\<log_file_name_with_date_and_time>.%~nx0.log"
exit /b
:IMPL
... here the rest of script ...
如果与tee实用程序一起使用,脚本和对脚本内一些实用程序的调用可能会中断输出。
gnuwin32的实现:
http://gnuwin32.sourceforge.net/packages/coreutils.htm
优点:
正确地处理标准输出和控制台进度条,其中\r字符被大量使用。
缺点:
使控制台进度条仅在日志文件中绘制,但在控制台窗口中没有复制或可见。 抛出多个错误消息Cwrite错误:没有这样的文件或目录,因为cmd解释器似乎过早地关闭了管道/stdout,并且在那之后不能自我关闭(垃圾邮件直到终止)。 不复制/打印控制台窗口中pause命令(按任意键继续…)的输出。
wintee实现:
https://code.google.com/archive/p/wintee/
https://github.com/rbuhl/wintee
优点:
在控制台窗口和日志文件(多次打印)中显示控制台进度条。 复制/打印控制台窗口中pause命令(按任意键继续…)的输出。
缺点:
错误地处理\r字符,输出是混合和混乱的(https://code.google.com/archive/p/wintee/issues/7)。 若有其他问题:https://code.google.com/archive/p/wintee/issues
UnxUtils实现:
http://unxutils.sourceforge.net/
https://sourceforge.net/projects/unxutils/files/unxutils/current/
Pros
在控制台窗口和日志文件(多次打印)中显示控制台进度条。 正确处理\r字符。 复制/打印控制台窗口中pause命令(按任意键继续…)的输出。
Cons
尚未发现
ss64.net实现:
http://ss64.net/westlake/nt
http://ss64.net/westlake/nt/tee.zip
优点:
在控制台窗口和日志文件(多次打印)中显示控制台进度条。
缺点:
错误地处理\r字符,输出混合和混乱 由于某种原因,在按下一个键后复制/打印控制台窗口中的pause命令(按任意键继续…)的输出。
ritchielawrence mtee实现:
https://ritchielawrence.github.io/mtee
https://github.com/ritchielawrence/mtee
Pros
在控制台窗口和日志文件(多次打印)中显示控制台进度条。 正确处理\r字符。 复制/打印控制台窗口中pause命令(按任意键继续…)的输出。 错误码保留特性w/o需要使用doskey的解决方案(/E标志,Windows命令解释器:如何获得第一个管道命令的退出码)
Cons
日志文件(https://github.com/ritchielawrence/mtee/issues/6)的路径不支持正斜杠字符 存在竞态条件问题,无法提取管道进程退出代码,因为它在访问之前已经关闭(https://github.com/ritchielawrence/mtee/issues/4)
因此,如果您在上述两种工具中选择tee实用程序实现,那么更好的选择是UnxUtils或mtee。
如果你正在寻找一个更好的实现,有更多的功能和更少的问题,那么你可以使用callf实用程序: https://github.com/andry81/contools/blob/trunk/Utilities/src/callf/help.tpl
你可以运行而不是:
call test.bat | mtee /E 1.log
这样的:
callf.exe /ret-child-exit /tee-stdout 1.log /tee-stdout-dup 1 "" "cmd.exe /c call test.bat"
它更好,因为它可以将stdout与stderr分开管道,甚至可以使用命名管道在具有管理员特权隔离的进程之间进行管道。
发送输出到控制台,附加到控制台日志,从当前命令删除输出
dir >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1
这是可行的,尽管它有点丑陋:
dir >_ && type _ && type _ > a.txt
它比其他一些解决方案更灵活一些,因为它是一条一条地工作的,所以您也可以使用它来追加。我在批处理文件中经常使用这种方法来记录和显示消息:
ECHO Print line to screen and log to file. >_ && type _ && type _ >> logfile.txt
是的,您可以只重复ECHO语句(一次用于屏幕,第二次重定向到日志文件),但这看起来同样糟糕,并且存在一些维护问题。至少这样您就不必在两个地方对消息进行更改。
注意_只是一个简短的文件名,所以你需要确保在批处理文件的末尾删除它(如果你使用的是批处理文件)。
就像unix一样。
目录 |茶A.txt
在windows XP上,它需要安装mksnt。
它显示在提示符上,并附加到文件中。