使用.bat文件的自定义Tee命令

我正在尝试使用为bat文件编写的T恤代码,但是在执行代码时遇到问题。 我不希望使用任何第三方安装来解决问题,因为如果我在一年内格式化计算机并希望再次运行该程序,我希望代码能够正常工作。

我有这样的设置:

mycommand.exe | tee.bat -a output.txt 

我已经试过了一个单独的.bat文件,并尝试包括作为一个函数(优先)在原来的.bat无济于事:

 myprogram.exe | call tee -a output.txt echo. echo. echo. SET /P restart="Do you want to run again? (1=yes, 2=no): " if "%restart%"=="1" GOTO LoopStart ::-------------------------------------------------------- ::-- Function section starts below here ::-------------------------------------------------------- :tee :: Check Windows version IF NOT "%OS%"=="Windows_NT" GOTO Syntax | :: Keep variables local SETLOCAL :: Check command line arguments SET Append=0 IF /I [%1]==[-a] ( SET Append=1 SHIFT ) IF [%1]==[] GOTO Syntax IF NOT [%2]==[] GOTO Syntax :: Test for invalid wildcards SET Counter=0 FOR /F %%A IN ('DIR /A /B %1 2^>NUL') DO CALL :Count "%%~fA" IF %Counter% GTR 1 ( SET Counter= GOTO Syntax ) :: A valid filename seems to have been specified SET File=%1 :: Check if a directory with the specified name exists DIR /AD %File% >NUL 2>NUL IF NOT ERRORLEVEL 1 ( SET File= GOTO Syntax ) :: Specify /Y switch for Windows 2000 / XP COPY command SET Y= VER | FIND "Windows NT" > NUL IF ERRORLEVEL 1 SET Y=/Y :: Flush existing file or create new one if -a wasn't specified IF %Append%==0 (COPY %Y% NUL %File% > NUL 2>&1) :: Actual TEE FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO ( > CON ECHO.%%B >> %File% ECHO.%%B ) :: Done ENDLOCAL GOTO:EOF :Count SET /A Counter += 1 SET File=%1 GOTO:EOF :Syntax ECHO. ECHO Tee.bat, Version 2.11a for Windows NT 4 / 2000 / XP ECHO Display text on screen and redirect it to a file simultaneously ECHO. IF NOT "%OS%"=="Windows_NT" ECHO Usage: some_command ¦ TEE.BAT [ -a ] filename IF NOT "%OS%"=="Windows_NT" GOTO Skip ECHO Usage: some_command ^| TEE.BAT [ -a ] filename :Skip ECHO. ECHO Where: "some_command" is the command whose output should be redirected ECHO "filename" is the file the output should be redirected to ECHO -a appends the output of the command to the file, ECHO rather than overwriting the file ECHO. ECHO Written by Rob van der Woude ECHO http://www.robvanderwoude.com ECHO Modified by Kees Couprie ECHO http://kees.couprie.org ECHO and Andrew Cameron 

我想分裂输出,所以我可以保存控制台输出到一个文件,同时仍然能够与正在运行的程序进行交互。

如何让我的.bat的Tee命令正常工作,这样我就可以将输出分割成文件和控制台。

由于Windowspipe道的工作方式,在pipe道中调用批处理函数的尝试总是失败–Windows通过新的CMD shell实例化pipe道的两端。 请参阅https://stackoverflow.com/a/8194279/1012053了解更多信息。;

Rob van der Woude版本的批量tee不能为你工作,因为它使用FOR /F来读取命令的结果 – 在读取任何行之前,命令必须执行完成。 如果在命令执行过程中需要用户交互,这将不起作用。 使用这个版本的T恤,你可能只需将输出redirect到一个文件,然后在完成时TYPE文件。 显然不是你想要的。

有一些纯粹的批量技巧可以让你更接近,但我认为还有一个问题是纯批量无法解决的。 您的可执行文件可能会提示一条线,而不会发出一个新行。 我相信纯本地批处理总是读整行(除了在stream结束时)。 我不知道批处理方法来逐字符读取。

轻微的修正SET /P可以读取pipe道input的部分行,但它有一些限制,使其不能用于强大的批量T恤解决scheme:当每行结束时无法确定。 每个“行”限制为1021个字符。 它从每个“行”的末尾去除控制字符。 没有办法知道它何时到达inputstream的末尾。

但有一个简单的解决scheme – JScript或VBScript就像一个冠军,并不需要任何特殊的安装。 这是一个混合的JScript /批处理脚本,应该为你工作。 JScript写得不好,有很大的改进空间。 例如,没有错误检查。

我将脚本保存为tee.bat 。 第一个必需的参数指定要写入的文件的名称。 默认情况下,如果文件已经存在,文件将被覆盖。 如果提供了第二个参数(值无关紧要),则输出将附加到文件中。

 @if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment ::--- Batch section within JScript comment that calls the internal JScript ---- @echo off cscript //E:JScript //nologo "%~f0" %* exit /b ----- End of JScript comment, beginning of normal JScript ------------------*/ var fso = new ActiveXObject("Scripting.FileSystemObject"); var mode=2; if (WScript.Arguments.Count()==2) {mode=8;} var out = fso.OpenTextFile(WScript.Arguments(0),mode,true); var chr; while( !WScript.StdIn.AtEndOfStream ) { chr=WScript.StdIn.Read(1); WScript.StdOut.Write(chr); out.Write(chr); } 

用法与您所期望的非常相似。

 command.exe | tee.bat output.txt 1 

最后1个参数强制追加模式。 它可以是除1之外的任何值

您可以将所有内容放在一个批处理脚本中,因为您似乎更喜欢这样做。

 @if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment ::--- Batch section within JScript comment ---------------------------- @echo off ::This block of code handles the TEE by calling the internal JScript code if "%~1"=="_TEE_" ( cscript //E:JScript //nologo "%~f0" %2 %3 exit /b ) ::The rest of your batch script goes here ::This pipes to TEE in append mode mycommand.exe | "%~f0" _TEE_ output.txt 1 exit /b ----- End of JScript comment, beginning of normal JScript ------------------*/ var fso = new ActiveXObject("Scripting.FileSystemObject"); var mode=2; if (WScript.Arguments.Count()==2) {mode=8;} var out = fso.OpenTextFile(WScript.Arguments(0),mode,true); var chr; while( !WScript.StdIn.AtEndOfStream ) { chr=WScript.StdIn.Read(1); WScript.StdOut.Write(chr); out.Write(chr); } 

更新

对于任何对批处理脚本有学术兴趣的人,我已经在DosTips上发布了一个纯asynchronous本地批处理脚本 。 但是这种混合方法是我的首选脚本解决scheme。