[windows] Redirecting Output from within Batch file

I am creating a batch file with some simple commands to gather information from a system. The batch file contains commands to get the time, IP information, users, etc.

I assembled all the commands in a batch file, and it runs, but I would like the batch file, when run to output the results to a text file (log). Is there a command that I can add to the batch that would do so?

Keep in mind I do not want to run the batch from cmd, then redirect output ; I want to redirect the output from inside the batch, if that is possible.

This question is related to windows batch-file cmd io-redirection

The answer is


The simple naive way that is slow because it opens and positions the file pointer to End-Of-File multiple times.

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

A better way - easier to write, and faster because the file is opened and positioned only once.

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

Another good and fast way that only opens and positions the file once

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

:sub
command1
command2
...
commandN

Edit 2020-04-17

Every now and then you may want to repeatedly write to two or more files. You might also want different messages on the screen. It is still possible to to do this efficiently by redirecting to undefined handles outside a parenthesized block or subroutine, and then use the & notation to reference the already opened files.

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

:sub
echo Screen message 1
>&9 File 1 message 1
>&8 File 2 message 1
echo Screen message 2
>&9 File 1 message 2
>&8 File 2 message 2
exit /b

I chose to use handles 9 and 8 in reverse order because that way is more likely to avoid potential permanent redirection due to a Microsoft redirection implementation design flaw when performing multiple redirections on the same command. It is highly unlikely, but even that approach could expose the bug if you try hard enough. If you stage the redirection than you are guaranteed to avoid the problem.

3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.

@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

There is a cool little program you can use to redirect the output to a file and the console

some_command  ^|  TEE.BAT  [ -a ]  filename 

_x000D_
_x000D_
@ECHO OFF_x000D_
:: Check Windows version_x000D_
IF NOT "%OS%"=="Windows_NT" GOTO Syntax_x000D_
_x000D_
:: Keep variables local_x000D_
SETLOCAL_x000D_
_x000D_
:: Check command line arguments_x000D_
SET Append=0_x000D_
IF /I [%1]==[-a] (_x000D_
 SET Append=1_x000D_
 SHIFT_x000D_
)_x000D_
IF     [%1]==[] GOTO Syntax_x000D_
IF NOT [%2]==[] GOTO Syntax_x000D_
_x000D_
:: Test for invalid wildcards_x000D_
SET Counter=0_x000D_
FOR /F %%A IN ('DIR /A /B %1 2^>NUL') DO CALL :Count "%%~fA"_x000D_
IF %Counter% GTR 1 (_x000D_
 SET Counter=_x000D_
 GOTO Syntax_x000D_
)_x000D_
_x000D_
:: A valid filename seems to have been specified_x000D_
SET File=%1_x000D_
_x000D_
:: Check if a directory with the specified name exists_x000D_
DIR /AD %File% >NUL 2>NUL_x000D_
IF NOT ERRORLEVEL 1 (_x000D_
 SET File=_x000D_
 GOTO Syntax_x000D_
)_x000D_
_x000D_
:: Specify /Y switch for Windows 2000 / XP COPY command_x000D_
SET Y=_x000D_
VER | FIND "Windows NT" > NUL_x000D_
IF ERRORLEVEL 1 SET Y=/Y_x000D_
_x000D_
:: Flush existing file or create new one if -a wasn't specified_x000D_
IF %Append%==0 (COPY %Y% NUL %File% > NUL 2>&1)_x000D_
_x000D_
:: Actual TEE_x000D_
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (_x000D_
 >  CON    ECHO.%%B_x000D_
 >> %File% ECHO.%%B_x000D_
)_x000D_
_x000D_
:: Done_x000D_
ENDLOCAL_x000D_
GOTO:EOF_x000D_
_x000D_
:Count_x000D_
SET /A Counter += 1_x000D_
SET File=%1_x000D_
GOTO:EOF_x000D_
_x000D_
:Syntax_x000D_
ECHO._x000D_
ECHO Tee.bat,  Version 2.11a for Windows NT 4 / 2000 / XP_x000D_
ECHO Display text on screen and redirect it to a file simultaneously_x000D_
ECHO._x000D_
IF NOT "%OS%"=="Windows_NT" ECHO Usage:  some_command  ³  TEE.BAT  [ -a ]  filename_x000D_
IF NOT "%OS%"=="Windows_NT" GOTO Skip_x000D_
ECHO Usage:  some_command  ^|  TEE.BAT  [ -a ]  filename_x000D_
:Skip_x000D_
ECHO._x000D_
ECHO Where:  "some_command" is the command whose output should be redirected_x000D_
ECHO         "filename"     is the file the output should be redirected to_x000D_
ECHO         -a             appends the output of the command to the file,_x000D_
ECHO                        rather than overwriting the file_x000D_
ECHO._x000D_
ECHO Written by Rob van der Woude_x000D_
ECHO http://www.robvanderwoude.com_x000D_
ECHO Modified by Kees Couprie_x000D_
ECHO http://kees.couprie.org_x000D_
ECHO and Andrew Cameron
_x000D_
_x000D_
_x000D_


I know this is an older post, but someone will stumble across it in a Google search and it also looks like some questions the OP asked in comments weren't specifically addressed. Also, please go easy on me since this is my first answer posted on SO. :)

To redirect the output to a file using a dynamically generated file name, my go-to (read: quick & dirty) approach is the second solution offered by @dbenham. So for example, this:

@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
)

Will create a file like what you see in this screenshot of the file in the target directory

That will contain this output:

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

Also keep in mind that this solution is locale-dependent, so be careful how/when you use it.


Add these two lines near the top of your batch file, all stdout and stderr after will be redirected to log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1

echo some output >"your logfile"

or

(
 echo some output
 echo more output
)>"Your logfile"

should fill the bill.

If you want to APPEND the output, use >> instead of >. > will start a new logfile.


if you want both out and err streams redirected

dir >> a.txt 2>&1

This may fail in the case of "toxic" characters in the input. Considering an input like thisIsAnIn^^^^put is a good way how to get understand what is going on. Sure there is a rule that an input string MUST be inside double quoted marks but I have a feeling that this rule is a valid rule only if the meaning of the input is a location on a NTFS partition (maybe it is a rule for URLs I am not sure). But it is not a rule for an arbitrary input string of course (it is "a good practice" but you cannot count with it).


Adding the following lines at the bottom of your batch file will grab everything just as displayed inside the CMD window and export into a text file:

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

It basically performs a select all -> copy into clipboard -> paste into text file.


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

I used the command above in my batch file and it works. In the log file, it shows the results of my command.


Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to batch-file

'ls' is not recognized as an internal or external command, operable program or batch file '' is not recognized as an internal or external command, operable program or batch file XCOPY: Overwrite all without prompt in BATCH Can´t run .bat file under windows 10 Execute a batch file on a remote PC using a batch file on local PC Windows batch - concatenate multiple text files into one How do I create a shortcut via command-line in Windows? Getting Error:JRE_HOME variable is not defined correctly when trying to run startup.bat of Apache-Tomcat Curl not recognized as an internal or external command, operable program or batch file Best way to script remote SSH commands in Batch (Windows)

Examples related to cmd

'ls' is not recognized as an internal or external command, operable program or batch file '' is not recognized as an internal or external command, operable program or batch file XCOPY: Overwrite all without prompt in BATCH VSCode Change Default Terminal How to install pandas from pip on windows cmd? 'ls' in CMD on Windows is not recognized Command to run a .bat file VMware Workstation and Device/Credential Guard are not compatible How do I kill the process currently using a port on localhost in Windows? how to run python files in windows command prompt?

Examples related to io-redirection

UTF-8 output from PowerShell Redirecting Output from within Batch file Redirect stderr to stdout in C shell Bash write to file without echo? What is /dev/null 2>&1? How to redirect both stdout and stderr to a file Redirect all output to file in Bash Send string to stdin Find and replace in file and overwrite file doesn't work, it empties the file How do I capture all of my compiler's output to a file?