Redirection of the output streams in DOS scripts

Just like most programming languages, DOS batch files provides you access to 2 types of output streams. The standard out (STDOUT) and standard error (STDERR). STDOUT is where most of your output is directed to. Whereas all error messages should be directed to the STDERR.
So, before getting into explaining how to use these different streams, you should probably know how DOS presents them. When doing redirection batch files use the number 1 to represent STDOUT and the number 2 to represent STDERR. By default, redirection is capturing the STDOUT stream. So the following statements both capture the STDOUT.
C:\>dir *.* > output.txt
C:\>dir *.* 1> output.txt
Now, if you're not familiar with the STDERR stream, the following displays how programs output to this stream and not the STDOUT.
C:\>dir NonExistentFile.txt > output.txt
File not found.
See how even though you captured the output, the text “File Not Found” was displayed? This is because it's coming from the STDERR stream and not the STDOUT. If you were to open the output.txt file you see that it's empty since nothing was sent to the STDOUT stream. Now if you wanted to capture the error stream, you could do something like the following examples.
C:\>dir /b NonExistentFile.txt 2> error.txt
C:\>dir /b NonExistentFile.txt 2> error.txt > output.txt
For both examples the error.txt file will contain the text “File Not Found”. The second examples is just illustrating that you can capture both streams to separate files in the same command. This can be useful if you want to capture all the errors to one file and all the other text to another file. But if you want to capture all output to just 1 file, you could do something like this.
C:\>dir /b * > allOutput 2>&1
C:\>dir /b NonExistentFile.txt > allOutput.txt 2>&1
In the first example, all the files and directories found in the C:\ will be listed in allOutput.txt. Whereas the second capture the error message “File Not Found” into allOutput.txt. What's happening here is that 2>&1 is telling the script to direct STDERR stream into STDOUT. This way you're redirecting all output into 1 file. This is very useful for recording information for debugging. You could direct the STDOUT to STDERR similarly by using 1>&2, but this is uncommon.
So far we've only shown examples of where we redirect STDOUT and STDERR to a file. What if we don't want to record the output to a file and would just rather redirect it into an oblivion? Well DOS reserves some file names for special uses. Among them is NUL which represents a null file. Linux scripters will recognize this as /dev/null. When you write to this file the content just disappears into the ether and is never to be seen again. I find this useful testing conditions and don't care about the output. Below are a couple of examples.
if exist logFile.txt del /f /s logFile.txt > NUL
where powershell.exe > NUL 2>&1
if ERRORLEVEL 1 (
echo ERROR: PowerShell is not installed; stopping.
goto :eof
)
In the first line I'm redirecting the message “Deleted file – logFile.txt” to NUL since this information has no importance to me. In the following section I don't care about any of the output text from the WHERE command is, I'm just interested in the error code it returns. So I redirect all output to NUL.
Hope you now have a better understanding of how the STDOUT and STDERR streams work in DOS and how they can give you a new level of control over your scripts. If you have any tips or tricks related to these, please post them in the comments below! It would be great to learn what other people are doing with them.



Reader Comments