批处理文件中的输出重定向

148

我正在创建一个批处理文件,其中包含一些简单的命令来从系统中获取信息。批处理文件包含获取时间、IP信息、用户等命令。

我将所有命令组装到了一个批处理文件中,并且它可以运行,但是当运行批处理文件时,我希望把结果输出到一个文本文件(日志)中。是否有一个命令可以添加到批处理中以实现这个目的?

请注意,我不想从cmd中运行批处理文件,然后重定向输出;如果可能的话,我想从批处理文件内部重定向输出。


我已经尝试了所有的解决方案,但是当我尝试使用 mycommand > myfile.txt 时,我的批处理文件会冻结。在我的批处理文件中,此后的任何命令都不会执行。 - HackerDaGreat57
10个回答

206

简单易懂的方式,但因为多次打开并将文件指针定位到文件末尾而速度较慢。

@echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt

更好的方法-易于编写,而且速度更快,因为文件只会被打开和定位一次。

@echo off
>output.txt (
  command1
  command2
  ...
  commandN
)

另一种快速且高效的方法,仅打开并定位文件一次。

@echo off
call :sub >output.txt
exit /b

:sub
command1
command2
...
commandN

编辑于2020-04-17

偶尔您可能希望重复写入两个或多个文件。您可能还希望在屏幕上显示不同的消息。仍然可以通过将输出重定向到括号内或子程序外的未定义句柄,并使用&符号引用已经打开的文件来高效地完成此操作。

call :sub 9>File1.txt 8>File2.txt
exit /b

:sub
echo Screen message 1
>&9 echo File 1 message 1
>&8 echo File 2 message 1
echo Screen message 2
>&9 echo File 1 message 2
>&8 echo File 2 message 2
exit /b
我选择反向使用9和8号句柄,因为那样更有可能避免由于Microsoft重定向实现设计缺陷在同一命令上执行多个重定向时发生潜在永久重定向的问题。虽然这种方法的可能性非常小,但是如果您够努力,甚至可以暴露该错误。如果你搭配使用重定向,你就能保证避免这个问题。
3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.

我知道这有点过时,但这是一个令人难以置信的功能,我从未意识到它的存在!我需要存储多个命令/应用程序的输出,但不能使用>> File.Log或2>>&1,因为命令/应用程序将其解释为不支持的参数。使用>> File.log 2>>&1(...)完美地解决了这个问题。绝对有兴趣了解其他类似的技巧! - JuliusPIV
@dbenham或其他人, 我喜欢第二个选项,即:echo off
output.txt ( command1 ... commandN )
但是有没有办法在其中打开回显。我尝试了不同的方法,但它从不打印正在执行的命令,只打印结果,这让人感到困惑,因为有时很难分辨哪个错误来自哪个命令。例如,这些方法不会记录命令: echo on
output.txt ( command1 commandN )
最后,我做了这个: echo on
output.txt ( echo command1 command1 )
- allmail

78

如果您想重定向标准输出和错误流

dir >> a.txt 2>&1

17

我知道这是一个旧帖子,但是有人会在Google搜索中偶然发现它,而且似乎OP在评论中提出的一些问题没有得到具体解答。另外,请原谅我,因为这是我在SO上发表的第一个回答。 :)

如果要将输出重定向到使用动态生成的文件名的文件中,我的常用方法(也就是快速且简单的方法)是@dbenham提供的第二个解决方案。例如:

@echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)

将创建一个像目标目录中文件截图所示的文件。

该文件将包含以下输出:

Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log

请记住,这个解决方案与语言环境相关,因此在使用时要小心。


12
@echo off
>output.txt (
echo Checking your system infor, Please wating...

systeminfo | findstr /c:"Host Name" 
systeminfo | findstr /c:"Domain"

ipconfig /all | find "Physical Address" 

ipconfig | find "IPv4" 
ipconfig | find "Default Gateway"

)

@pause

11
echo some output >"your logfile"
或者
(
 echo some output
 echo more output
)>"Your logfile"

如果你想要追加输出,使用>>代替>>会开启一个新的日志文件。


6
在批处理文件的顶部添加以下两行代码,之后所有标准输出和标准错误都将被重定向到log.txt文件中:
if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1

5

有一个很酷的小程序可以将输出重定向到文件和控制台

some_command  ^|  TEE.BAT  [ -a ]  filename 

@ECHO OFF
:: 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


4
@echo OFF
[your command] >> [Your log file name].txt

我在批处理文件中使用了上述命令,它可以正常工作。在日志文件中,它显示了我的命令的结果。


3
在您的批处理文件底部添加以下行,将抓取CMD窗口内显示的所有内容并导出到文本文件中:
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt

它基本上执行的是“全选”->“复制到剪贴板”->“粘贴到文本文件”的操作。

-1

在输入中存在“有毒”字符的情况下,此操作可能会失败。 考虑到像 thisIsAnIn^^^^put 这样的输入是了解正在发生的事情的好方法。 当然,有一个规则,即输入字符串必须在双引号中,但我有一种感觉,这个规则只适用于输入的含义是 NTFS 分区上的位置(也许这是 URL 的规则,我不确定)。 但对于任意输入字符串来说,这并不是一个规则(这是“良好的实践”,但您不能指望它)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接