Stuff I Learned Scripting - Fun with STDERR
Say you’re writing a long Windows CMD script, something like an audit script that’ll take a good 20-30 minutes to complete.
Now say the whole script is being redirected to a report file - as scripts get more complicated, I'm finding that almost everything I write ends up doing this. Something like below (just to pick a random SEC579 example):
audit-esx.cmd servername userid password > reportfile.html
If all goes well, you see *nothing* on your screen for the next 20+ minutes (unless you’ve got a good port of tee available) – but if it gets stuck, it's going to be 20+ minutes, or likely longer, before you realize that your script is borked …
What to do? What to do? - - Use STDERR !
As the script goes through, insert an echo for each test (or meaningful phase) in your script to STDERR:
echo Audit Check SomeMeaningfulName >&2
or, if you’ve parameterized your script enough:
echo Check %CHK% >&2
"&2" means "send this to STDERR".
So, instead of a blank screen as the audit runs, the screen will be a show you useful info on it's progress:
C:\sans\sec579\audit>audit-vms esx01.sec579.com root Passw0rd > esx01-audit-vms.html
Audit Check VMX01
Audit Check VMX02
Audit Check VMX10
Audit Check VMX11
Audit Check VMX12
Audit Check VMX20
Audit Check VMX21
Audit Check VMX22
… and so on, until it's done
Another neat trick will allow you to echo to a file AND to STDERR in windows. The example below will take the output of "somecommand", echo it to STDERR (which you'll see on the screen), and also echo it to the file "outputfile.txt"
somecommand > &2 > outputfile.txt
In linux, I'd normally do this using "tee" as mentioned, mostly because I'm lazy. The problem in this case with using tee is that it goes to STDOUT, rather than to STDERR, so if you're using it in combination with other redirection, you may not get what you expect:
somecommand | tee outputfile.txt
To fix this, you might string your command serially with cat, but that means that you won't see the command output on STDERR until the command is completely finished, rather than in (more or less) real time.
somecommand > outputfile.txt ; cat outputfile.txt >&2
To see everything at the same time, I'll still use tee, but we'll also use a temp file descriptor (3) and dump the STDOUT output of tee to STDERR, as shown below
(somecommand | tee outfile.txt) 3>&2
I hope this was useful - if you've got a neat take on using STDERR, or STDIN or STDOUT for that matter, in Windows (or *nix) scripts, by all means pass them along in our comment form !
===============
Rob VandenBrink
Metafore
Comments
To redirect both STDOUT and STDERR to the same file, do this:
somecommand > outputfile.txt 2> outputfile.txt
Or following Rob's handle names, redirect STDERR to STDOUT and then redirect STDOUT to the destination file:
somecommand 2>&1 > outputfile.txt
And because there's more than one way to do it, use TEE and TAIL from the GnuWin32 ports of classic *nix command line tools to Windows, available here: http://gnuwin32.sourceforge.net/
Then you can tee in the middle of your redirection, or if you realize later that your script is still running, run tail on the output file:
tail outputfile.txt
Or use tail to continually update the progress by following the updates to the file:
tail -F outputfile.txt
(presumably, you'd open a new command line window, because the first one is still busy waiting for your script to finish)
Andrew from Vancouver
Jan 12th 2012
1 decade ago
Even with Microsoft pushing their *nix toolset (which is pretty good) as part of Windows, I still find myself using the gnuwin32 set more often than not, only because I can pull a single executable and use it in a client environment, without installing anything on their servers or workstations.
Rob VandenBrink
Jan 12th 2012
1 decade ago
Justin
Jan 12th 2012
1 decade ago
Anonymous
Jan 12th 2012
1 decade ago
yourcommand | tee /dev/stderr
Anon
Jan 16th 2012
1 decade ago