Friday, September 7, 2007

Redirecting DOS stdout stderr

Every time I need to redirect DOS output I have to go look it up. There is only so much space in my brain and unless I want to forget how to speak something had to go. Well I got tired of searching thru different sites to get what I wanted, so the last time I came across this info (this happens to be from Microsoft) I posted it here.


Using command redirection operators

The following table lists operators that you can use to redirect command input and output streams.

Redirection operator Description

>

Writes the command output to a file or a device, such as a printer, instead of the Command Prompt window.

<

Reads the command input from a file, instead of reading input from the keyboard.

>>

Appends the command output to the end of a file without deleting the information that is already in the file.

>&

Writes the output from one handle to the input of another handle.

<&

Reads the input from one handle and writes it to the output of another handle.

|

Reads the output from one command and writes it to the input of another command. Also known as a pipe.

By default, you send the command input (that is, the STDIN handle) from your keyboard to Cmd.exe, and then Cmd.exe sends the command output (that is, the STDOUT handle) to the Command Prompt window.

The following table lists the available handles.

Handle Numeric equivalent of handle Description

STDIN

0

Keyboard input

STDOUT

1

Output to the Command Prompt window

STDERR

2

Error output to the Command Prompt window

UNDEFINED

3-9

These handles are defined individually by the application and are specific to each tool.

The numbers zero through nine (that is, 0-9) represent the first 10 handles. You can use Cmd.exe to run a program and redirect any of the first 10 handles for the program. To specify which handle you want to use, type the number of the handle before the redirection operator. If you do not define a handle, the default < redirection input operator is zero (0) and the default > redirection output operator is one (1). After you type the < or > operator, you must specify where you want to read or write the data. You can specify a file name or another existing handle.

To specify redirection to existing handles, use the ampersand (&) character followed by the handle number that you want to redirect (that is, &handle#). For example, the following command redirects handle 2 (that is, STDERR) into handle 1 (that is, STDOUT):

1<&2

Duplicating handles

The & redirection operator duplicates output or input from one specified handle to another specified handle. For example, to send dir output to File.txt and send the error output to File.txt, type:

dir>c:\file.txt 2>&1

When you duplicate a handle, you duplicate all characteristics of the original occurrence of the handle. For example, if a handle has write-only access, all duplicates of that handle have write-only access. You cannot duplicate a handle with read-only access into a handle with write-only access.

Redirecting command input (<)

To redirect command input from the keyboard to a file or device, use the < operator. For example, to get the command input for the sort command from File.txt:

sort<file.txt

The contents of File.txt appear in the Command Prompt window as an alphabetized list.

The < operator opens the specified file name with read-only access. As a result, you cannot write to the file when you use this operator. For example, if you start a program with <&2, all attempts to read handle 0 fail because handle 2 is initially opened with write-only access.

Redirecting command output (>)

Almost all commands send output to your Command Prompt window. Even commands that send output to a drive or printer display messages and prompts in the Command Prompt window.

To redirect command output from the Command Prompt window to a file or device, use the > operator. You can use this operator with most commands. For example, to redirect dir output to Dirlist.txt:

dir>dirlist.txt

If Dirlist.txt does not exist, Cmd.exe creates it. If Dirlist.txt exists, Cmd.exe replaces the information in the file with the output from the dir command.

To run the netsh routing dump command and then send the command output to Route.cfg, type:

netsh routing dump>c:\route.cfg

The > operator opens the specified file with write-only access. As a result, you cannot read the file when you use this operator. For example, if you start a program with redirection >&0, all attempts to write handle 1 fail because handle 0 is initially opened with read-only access.

Note

One is the default handle for the > redirection output operator.

Using the <& operator to redirect input and duplicate

To use the redirection input operator <&, the file you specify must already exist. If the input file exists, Cmd.exe opens it as read-only and sends the characters contained in the file as input to the command as if they were input from the keyboard. If you specify a handle, Cmd.exe duplicates the handle you specify onto the existing handle in the system.

For example, to open File.txt as input read to handle 0 (that is, STDIN), type:

<file.txt

To open File.txt, sort the contents and then send the output to the Command Prompt window (that is, STDOUT), type:

sort<file.txt

To find File.txt, and then redirect handle 1 (that is, STDOUT) and handle 2 (that is, STDERR) to the Search.txt, type:

findfile file.txt>search.txt 2<&1

To duplicate a user-defined handle 3 as input read to handle 0 (that is, STDIN), type:

<&3

Using the >& operator to redirect output and duplicate

If you redirect output to a file and you specify an existing file name, Cmd.exe opens the file as write-only and overwrites the file's contents. If you specify a handle, Cmd.exe duplicates the file onto the existing handle.

To duplicate a user-defined handle 3 into handle 1, type:

>&3

To redirect all of the output, including handle 2 (that is, STDERR), from the ipconfig command to handle 1 (that is, STDOUT), and then redirect the ouput to Output.log, type:

ipconfig.exe>>output.log 2>&1

Using the >> redirection operator to append output

To add the output from a command to the end of a file without losing any of the information already in the file, use two consecutive greater than signs (that is, >>). For example, the following command appends the directory list produced by the dir command to the Dirlist.txt file:

dir>>dirlist.txt

To append the output of the netstat command to the end of Tcpinfo.txt, type:

netstat>>tcpinfo.txt

Using the pipe operator (|)

The pipe operator (|) takes the output (by default, STDOUT) of one command and directs it into the input (by default, STDIN) of another command. For example, the following command sorts a directory:

dir | sort

In this example, both commands start simultaneously, but then the sort command pauses until it receives the dir command's output. The sort command uses the dir command's output as its input, and then sends its output to handle 1 (that is, STDOUT).

Combining commands with redirection operators

You can create custom commands by combining filter commands with other commands and file names. For example, you can use the following command to store the names of files that contain the string "LOG":

dir /b | find "LOG" > loglist.txt

The dir command's output is sent through the find filter command. File names that contain the string "LOG" are stored as a list of file names (for example, NetshConfig.log, Logdat.svd, and Mylog.bat) in the Loglist.txt file.

To use more than one filter in the same command, separate the filters with a pipe (|). For example, the following command searches every directory on drive C:, finds the file names that include the string "Log", and then displays them in one Command Prompt window at a time:

dir c:\ /s /b | find "LOG" | more

By using a pipe (|), you direct Cmd.exe to send the dir command output through the find filter command. The find command selects only file names that contain the string "LOG." The more command displays the file names that are selected by the find command, one Command Prompt window at a time. For more information about filter commands, see Using filters


27 comments:

Anonymous said...

This article, "Redirecting DOS stdout stderr", is a COPY of Microsoft's own words on this subject. It seems to me that folks who have nothing to add to the words of Microsoft ought to simply be quiet! Your duplication is NOT USEFUL, AND MISLEADING.

For Example: Redirection is as old as DOS, and is EASY. I guess I'm a bit dense right now, because I'm looking all over the web for some more info about this HANDLE redirect stuff. I simply don't get Microsoft's explanation of it. I go to non-MS websites to GET A DIFFERENT TAKE ON THE SUBJECT, not to read the same old explanation again! This article, which simply parrots Microsoft, is a gigantic waste of cyber-ink, bandwidth, and search-engine cycles, not to mention readers' time. If you want to publish something, ADD VALUE TO THE DISCUSSION. SPEAK IN YOUR OWN VOICE AND WITH YOUR OWN EXPERIENCE.

Shaune said...

If you took the time to read the very first paragraph you would see clearly I stated this was a copy from Microsoft. And the only reason for the post was so I could more easily find it when I needed it.

I have an idea if you don't like what you read here go some place else.

It seems to me that people just like to bitch, because they are under the mistaken opinion that what they think actually matters.

Anonymous said...

Go somewhere else this site is not for you! I am grateful I found this blog. Thanks Shaune, I think he read only the first paragraph.

Shaune said...

:)

Anonymous said...

Could just be me, but 1<&2 seems to put STDOUT to STDERR.

2<&1 did what I actually wanted, redirect STDERR to STDOUT.

Maybe I misread that paragraph above...

Anonymous said...

I am more concerned of the re-directing case using "2>&1", however, this doesn't work for me with DOS/telnet commmand.

Specifically, say, use following command ("mysvr" is a server name, 500 is TCP port#), and assume this port is not opened, hence you should see a msg "Connecting to mysvr... Could not open..."

DOS> telnet mysvr 500
Connecting to mysvr... Could not open..

The thing is this warning msg never goes to a log file even if trying follow:

DOS> telnet mysvr 500 >log.txt 2>&1

The log.txt is created but having a 0 size.

Can anybody shed more light? Really appreciate.

Shaune said...

Well Anonymous, all I can say is it must be using some special handle to output. I did try redirecting the other handles
"telnet mysvr 500 >log.txt 4>&1"

"telnet mysvr 500 >log.txt 5>&1"


with no luck.

Anonymous said...

Shaune,

I appreciate your tries and reply though no luck - It's MS evil.

Shaune said...

no problem. Yes they can be but I also would be with out a job if it wasn't for them :)

Anonymous said...

Hi, do you also know how i can redirect stdout and stderr to a HANDLE in my code (what you were talking about was from command-line). What i wish yo do is catch all stdout and stderr in my C++ code and keep them in a string that would be used in the end of my program...
thanks

pname said...
This comment has been removed by the author.
pname said...

Do you have ever try to change where stands 'stdout' or 'stderr' stands,in da code by one of Seven others output-flowZ ? (i.e. by '3', '4', '5', '6', '7', '8', '9' ) ... ⌂

Shaune said...

No I haven't, I actually do very little command line programming. The only 2 I have every had to deal with is STDOUT and STDERR

Devarishi said...

Hi,

Thanks for this post. I needed to know how to redirect standard error into a file.

Thanks!

Dev.

Anonymous said...

Is there a way to redirect a dos command (regedit) which requires a file as output to redirect the output to stdout instead? I.e. trick it to write to the screen or clipboard and not to a file at all. I do not wish to create and delete a file to extract some basic reg data.

Nico D. said...

Thanks a lot for your post. Microsoft's post is not as easy to find as this one and really helped me in my project.

Now my question: I want to redirect output both to the console and a file.
I've tried 'dir > con > file.txt' and variations but just couldn't find the proper combination.

Does anyone have an idea?

Thanks!

Anonymous said...

Wow! what an idea ! What a concept ! Beautiful .. Amazing …

rH3uYcBX

said...

Thank's³ :
1) to take time to answer to me, as wird I can be when I did not think wide @all; and even if it took me nearly one year to see I've get a 3h's back answer :}
In fact I try to make out a kind of stack by handling handles ...
If I may :
more XXXX 1>&3 | del XXXX /f /q | more 0<&3 >XXXX

2) Oh I forgotten but nothing too important, this is by that blog entry that I've evolved at my level (so far not an exemple, but), so thank's to the will to your need, if I may so.

3) Since I'm bad @ langage, thank's you for your efforts.

said...

Thank's³ :
1) to take time to answer to me, as wird I can be when I did not think wide @all; and even if it took me nearly one year to see I've get a 3h's back answer :}
In fact I try to make out a kind of stack by handling handles ...
If I may :
more XXXX 1>&3 | del XXXX /f /q | more 0<&3 >XXXX

2) Oh I forgotten but nothing too important, this is by that blog entry that I've evolved at my level (so far not an exemple, but), so thank's to the will to your need, if I may so.

3) Since I'm bad @ langage, thank's you for your efforts.

Anonymous said...

PsGetSid S-1-5-32-544 2>NUL | findstr /R "Alias:" 3<sid.txt
set /p Admins=0<sid.txt

... and cut in desired form

puts the admins name to a variable.

-- Is there any possibility to pipe the output of FINDSTR to the input of the SET command without using a data file? e.g. through one of the pipes like &5.

Tried it but it did not work.

Anonymous said...

I'd go this route 'Anonymous':

for /f "tokens=2 delims= " %%a in ('psgetsid S-1-5-32-544 2^>nul ^| findstr /r "Alias:"') do set Admins=%%a

Anonymous said...

Thanks! Reference was accurate and easy to find with Google.

Anonymous said...

Thanks for posting this in a way that can actually be easily found via google!

Anonymous said...

Thanks for posting. Your site comes up on top of a google Search for "stderr redirect dos" - not Micro$oft :-)

Many thanks!

Shaune said...

Most Welcome! I am glad to see this is still of use to people

Anonymous said...

... and it's STILL of use!

Shaune said...

I am very glad to hear people still find this useful :-)