I have a batch script that executes a task and sends the output to a text file. Is there a way to have the output show on the console window as well?
For Example:
c:\Windows>dir > windows-dir.txt
Is there a way to have the output of dir
display in the console window as well as put it into the text file?
This question is related to
windows
batch-file
cmd
I made a simple C# console which can handle real-time output to both cmd screen and log
class Tee
{
static int Main(string[] args)
{
try
{
string logFilePath = Path.GetFullPath(args[0]);
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
for (int value; (value = Console.In.Read()) != -1;)
{
var word = Char.ConvertFromUtf32(value);
Console.Write(word);
writer.Write(word);
}
}
}
catch (Exception)
{
return 1;
}
return 0;
}
}
The batch file usage is the same as how you use Unix tee
foo | tee xxx.log
And here is the repository which includes the Tee.exe in case you don't have tool to compile https://github.com/iamshiao/Tee
I like atn's answer, but it was not as trivial for me to download as wintee, which is also open source and only gives the tee functionality (useful if you just want tee and not the entire set of unix utilities). I learned about this from davor's answer to Displaying Windows command prompt output and redirecting it to a file, where you also find reference to the unix utilities.
command > file >&1
I think you want something along the lines of this:
echo Your Msg> YourTxtFile.txt
Or if you want a new line:
echo Your Msg>> YourTxtFile.txt
These commands are great for logs.
Note: This will sometimes glitch and replace the whole text file on my computer.
Another Note: If the file does not exist, it will create the file.
The solution that worked for me was: dir > a.txt | type a.txt.
If you don't need the output in real time (i.e. as the program is writing it) you could add
type windows-dir.txt
after that line.
command > file >&1
I made a simple C# console which can handle real-time output to both cmd screen and log
class Tee
{
static int Main(string[] args)
{
try
{
string logFilePath = Path.GetFullPath(args[0]);
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
for (int value; (value = Console.In.Read()) != -1;)
{
var word = Char.ConvertFromUtf32(value);
Console.Write(word);
writer.Write(word);
}
}
}
catch (Exception)
{
return 1;
}
return 0;
}
}
The batch file usage is the same as how you use Unix tee
foo | tee xxx.log
And here is the repository which includes the Tee.exe in case you don't have tool to compile https://github.com/iamshiao/Tee
The solution provided by "Tomas R" works perfect for the OP's question and it natively available.
Try: chkdsk c: > output.txt | type output.txt
The output is of this command involves a completion percentage that gets serially output to the file hence it will look a bit messy (i.e. the text will be appended as it progress). This does not happen to the bits that gets output to STDOUT (the screen). It is how it would be if you just do the same command without redirection.
Yes, there is a way to show a single command output on the console (screen) and in a file. Using your example, use...
@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt
Detailed explanation:
The FOR
command parses the output of a command or text into a variable, which can be referenced multiple times.
For a command, such as DIR /B
, enclose in single quotes as shown in example below. Replace the DIR /B
text with your desired command.
FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT
For displaying text, enclose text in double quotes as shown in example below.
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT
... And with line wrapping...
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
ECHO %%I & ECHO %%I>>FILE.TXT
)
If you have times when you want the output only on console (screen), and other times sent only to file, and other times sent to both, specify the "DO" clause of the FOR loop using a variable, as shown below with %TOECHOWHERE%
.
@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
FOR %%J IN (TRUE FALSE) DO (
SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish
:Runit
REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
REM above when the FOR loops are evaluating the first item in the list,
REM "TRUE". So, the first value of TOSCREEN is "TRUE " (with a trailing
REM space), the second value is "FALSE" (no trailing or leading space).
REM Adding the ": =" text after "TOSCREEN" tells the command processor to
REM remove all spaces from the value in the "TOSCREEN" variable.
IF "%TOSCREEN: =%"=="TRUE" (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=On screen, and in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
) ELSE (
SET TEXT=On screen, not in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I"
)
) ELSE (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=Not on screen, but in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>>FILE.txt"
) ELSE (
SET TEXT=Not on screen, nor in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>NUL"
)
)
FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof
:Finish
ECHO Finished [this text to console (screen) only].
PAUSE
If you want to append instead of replace the output file, you may want to use
dir 1>> files.txt 2>> err.txt
or
dir 1>> files.txt 2>>&1
Just use the Windows version of the UNIX tee command (found from http://unxutils.sourceforge.net) in this way:
mycommand > tee outpu_file.txt
If you also need the STDERR output, then use the following.
The 2>&1
combines the STDERR output into STDOUT (the primary stream).
mycommand 2>&1 | tee output_file.txt
If you don't need the output in real time (i.e. as the program is writing it) you could add
type windows-dir.txt
after that line.
The solution provided by "Tomas R" works perfect for the OP's question and it natively available.
Try: chkdsk c: > output.txt | type output.txt
The output is of this command involves a completion percentage that gets serially output to the file hence it will look a bit messy (i.e. the text will be appended as it progress). This does not happen to the bits that gets output to STDOUT (the screen). It is how it would be if you just do the same command without redirection.
If you don't need the output in real time (i.e. as the program is writing it) you could add
type windows-dir.txt
after that line.
I think you want something along the lines of this:
echo Your Msg> YourTxtFile.txt
Or if you want a new line:
echo Your Msg>> YourTxtFile.txt
These commands are great for logs.
Note: This will sometimes glitch and replace the whole text file on my computer.
Another Note: If the file does not exist, it will create the file.
My option was this:
Create a subroutine that takes in the message and automates the process of sending it to both console and log file.
setlocal
set logfile=logfile.log
call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"
goto :eof
:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b
If you add a variable to the message, be sure to remove the quotes in it before sending it to the subroutine or it can screw your batch. Of course this only works for echoing.
The solution that worked for me was: dir > a.txt | type a.txt.
If you don't need the output in real time (i.e. as the program is writing it) you could add
type windows-dir.txt
after that line.
command > file >&1
If you want to append instead of replace the output file, you may want to use
dir 1>> files.txt 2>> err.txt
or
dir 1>> files.txt 2>>&1
Just use the Windows version of the UNIX tee command (found from http://unxutils.sourceforge.net) in this way:
mycommand > tee outpu_file.txt
If you also need the STDERR output, then use the following.
The 2>&1
combines the STDERR output into STDOUT (the primary stream).
mycommand 2>&1 | tee output_file.txt
Yes, there is a way to show a single command output on the console (screen) and in a file. Using your example, use...
@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt
Detailed explanation:
The FOR
command parses the output of a command or text into a variable, which can be referenced multiple times.
For a command, such as DIR /B
, enclose in single quotes as shown in example below. Replace the DIR /B
text with your desired command.
FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT
For displaying text, enclose text in double quotes as shown in example below.
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT
... And with line wrapping...
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
ECHO %%I & ECHO %%I>>FILE.TXT
)
If you have times when you want the output only on console (screen), and other times sent only to file, and other times sent to both, specify the "DO" clause of the FOR loop using a variable, as shown below with %TOECHOWHERE%
.
@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
FOR %%J IN (TRUE FALSE) DO (
SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish
:Runit
REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
REM above when the FOR loops are evaluating the first item in the list,
REM "TRUE". So, the first value of TOSCREEN is "TRUE " (with a trailing
REM space), the second value is "FALSE" (no trailing or leading space).
REM Adding the ": =" text after "TOSCREEN" tells the command processor to
REM remove all spaces from the value in the "TOSCREEN" variable.
IF "%TOSCREEN: =%"=="TRUE" (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=On screen, and in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
) ELSE (
SET TEXT=On screen, not in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I"
)
) ELSE (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=Not on screen, but in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>>FILE.txt"
) ELSE (
SET TEXT=Not on screen, nor in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>NUL"
)
)
FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof
:Finish
ECHO Finished [this text to console (screen) only].
PAUSE
I like atn's answer, but it was not as trivial for me to download as wintee, which is also open source and only gives the tee functionality (useful if you just want tee and not the entire set of unix utilities). I learned about this from davor's answer to Displaying Windows command prompt output and redirecting it to a file, where you also find reference to the unix utilities.
command > file >&1
My option was this:
Create a subroutine that takes in the message and automates the process of sending it to both console and log file.
setlocal
set logfile=logfile.log
call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"
goto :eof
:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b
If you add a variable to the message, be sure to remove the quotes in it before sending it to the subroutine or it can screw your batch. Of course this only works for echoing.
Source: Stackoverflow.com