我正在尝试使用为bat文件编写的tee代码,但在我的代码中实现它时遇到了问题。我不想使用任何第三方安装来解决开球问题,因为如果我在一年内格式化我的电脑并希望再次运行该程序,我希望代码能够正常工作。
我以这种方式设置它:
mycommand.exe | tee.bat -a output.txt
我尝试使用单独的.bat
文件并尝试在原始.bat
中包含作为函数(preffered)但无效:
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
我正在尝试拆分输出,这样我就可以将控制台输出保存到文件中,同时仍然可以与正在运行的程序进行交互。
如何让Tee命令与我的.bat一起正常工作,这样我就可以将输出拆分为文件和控制台。
答案 0 :(得分:22)
由于Windows管道的工作方式,您尝试在管道中调用批处理函数将始终失败 - Windows通过新的CMD shell实例化管道的两侧。有关详细信息,请参阅https://stackoverflow.com/a/8194279/1012053。
批量T恤的Rob van der Woude版本不可能为您工作,因为它使用FOR /F
来读取命令的结果 - 命令必须在读取任何行之前执行完成。如果在执行命令期间需要用户交互,那将无效。使用该版本的tee,您可以简单地将输出重定向到文件,然后在完成后将TYPE
文件重定向。显然不是你想要的。
有一些纯粹的批处理技巧可以让你更接近,但我认为仍有一个问题无法通过纯批处理解决。您的可执行文件可能会在一行上发出提示,而不会发出新行。我相信纯本地批处理总是读取整行(除了在流的末尾)。我不知道按字符读取的批处理方法。
轻微修正 - SET /P
可以读取管道输入的部分行,但它有一些限制,可以防止它被用于强大的批处理tee解决方案:无法确定每条线路何时结束。每条“线”限制为1021个字符。它从每个“行”的末尾剥离控制字符。没有办法告诉它何时到达输入流的末尾。
但是有一个简单的解决方案--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
之外,它可以是任何值可以将所有内容放在一个批处理脚本中,因为您似乎更喜欢这样。
@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 native batch tee script以上的纯粹原生批量版本的tee。但这种混合方法是我首选的脚本解决方案。