is there a way to distinguish stderr in console output? - batch-file

That is display both streams on console but distinguish somehow one from another.
Normally is that I don't know which lines are stderr they are mixed with normal output. If I redirect it to a file then I don't know when in relation to normal output the error happened. So is there a way so every line that comes from stderr would have some indicator like for example a string at the beginning like this:
c:\>command.exe
normal output
normal output
normal output
stderr: error message
normal output
stderr: error message
normal output
This is especially problem in compilers/make which spew lot of information and mix those two streams. I know I can prepend every line of text with given string using unix sed but I do not know how to use it with relation to main program. If I join two streams string will be prepended to every line. If I redirect stderr to file it won't be displayed on console + it will get out of context from stdout.

If the purpose is to distinguish error messages from normal output in the same screen, then it may be done via this trick:
anycompiler params ... 2>&1 1>&3 | findstr /N /A:4E "^"
This way the error messages appears preceded by a line number in yellow color on red background.
Previous answer extracted from: Batch - How can I redirect stderr and stdout from within the batch script itself?
If you redirect both outputs of previous line to a disk file, STDERR output will be preceded by a line number.

Related

Can't output certain line to batch file

I'm using a batch file to create an RDP file using various variables to populate the contents.
Every line uses an Echo command and then outputs to a file with >>
For instance -
#echo screen mode id:i:1>> "C:\TEMP\file.RDP"
#echo use multimon:i:1>> "C:\TEMP\file.RDP"
Whilst this works for every line, one single line is giving me a problem and will not output -
#echo selectedmonitors:s:2,0>> "C:\TEMP\file.RDP"
For some reason, this line actually outputs selectedmonitors:s:2, (the 0 disappears) to the command window and outputs nothing into the .RDP file.
Whilst #echo selectedmonitors:s:2,0 works in the command window and outputs as expected, I can't output to a file.
What's going wrong here?
>> is just an abbreviation for 1>>, where 1 is an output stream.
There are ten of those streams:
0 is STDIN (Input) and not allowed for redirecting output.
1 is STDOUT("normal" output), 2 is STDERR (error output)
and 3 to 9 are not defined (but usable).
Remove the # to see what happens:
A batch file like
echo selectedmonitors:s:2,0>>file.txt
shows as executed command:
echo selectedmonitors:s:2, 0>>file.txt
which tries to redirect Stream 0 (STDIN) (which holds nothing here) to the file.
The reason your other lines are working is that , is a standard delimiter and : is not, so the comma snips the zero off the echo and adds it to the redirection while the colon doesn't.
Two possible workarounds:
>>file.txt echo selectedmonitors:s:2,0
(echo selectedmonitors:s:2,0)>>file.txt
Try the following, instead.
#(echo selectedmonitors:s:2,0)>> "C:\TEMP\file.RDP"
Without the parentheses, and since the , comma works as a delimiter in batch command lines (see cmd- comma to separate parameters Compared to space? for example) the last token in the command is parsed as 0>> "C:\TEMP\file.RDP" which literally means "append stream 0 output to the given file". Since stream 0 is the standard input stream, this is invalid and ignored, but the "0" parameter gets "eaten" in the process.

What is the difference between stdout and stderr in C?

In C, stdout and stderr both print to the console window by default. Is there any difference between stderr and stdout other than the level of buffering?
One of the differences between stdout and stderr is the level of buffering. In §7.21.3 Files ¶7, the C11 standard says:
At program startup, three text streams are predefined and need not be opened explicitly -- standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
Typically, that means that standard output is line buffered (so the data is flushed when a newline is printed, or when the buffer is full), whereas standard error is either line buffered or unbuffered. These characteristics can be changed, of course.
The purpose of the standard error stream is to separate error messages from regular output. This is important in contexts such as shell scripts, where the standard output might be sent to a pipe or to a file. That redirection leaves standard error still going to a different place — usually the terminal. You can capture the standard output separately from the standard error too, at least if the shell is sufficiently powerful.
program > file
program | filter
program 2> error.log | filter
program > file 2> error.log
program 2> error.log
The first two leave the error messages visible on the terminal. The last three capture the error messages in the file error.log — sending the standard output to the filter program, the file or to the terminal window respectively.
By separating the error messages from the standard output, the programs down the pipeline (filter in my example) don't have to interpret the error messages from program, which makes them much, much simpler.
If running a program from the console, or via a batch file, or via a shortcut, use > or 1> to redirect stdout to a file, and use 2> to redirect stderr to a file. For example if reading from stdin, and writing to both stdout and stderr:
myprog <input.txt >output.txt 2>error.txt
or if you want stdout to a file, but stderr to display on the screen, use:
myprog <input.txt >output.txt
stderr is - well - the place for errors. It is really useful. Like make - if a program's return code is not 0 (it completed with errors), it will print stderr. stderr can not be differentiated from stdout by the user, but it's still the recommended place for errors. However, if your program will be run by any automatization program, shell script etc... it can be used to track errors, and always use it.

Why use stderr when printf works fine?

Why should we use stderr when printing a custom error message from printf works fine?
For example why use stderr at all when I can just write a statement like this:
printf("error! you didn't... blah blah blah");
It is good practice to redirect all error messages to stderr, while directing regular output to stdout. It is beneficial to do this because anything written to stderr is not buffered, i.e., it is immediately written to the screen so that the user can be warned immediately.
stderr stands for standard error stream.
In console programming, it is the console -- the screen. It is essentially the same as stdout.
The general practice is to redirect all error messages to stderr and all regular output to stdout.
The reason is that it is possible to redirect standard output to a file instead of the screen. So If you perform a dir > dirlist.txt command on the command prompt, the directory listing goes into the text file instead of the screen. If you code to redirect error messages to stderr, the errors will always go to the screen instead of the file so that the user could be warned immediately instead of ending up seeing unexpected results in the file.
Using printf() will display the error message to the console, which will be stored in the stdout buffer, but using stderr, is different.
stderr can be used as an argument for any function that takes an argument of type FILE* expecting an output stream, like fputs or fprintf.
Although in many cases, both stdout and stderr are associated with the same output device (like the console), applications may differentiate between what is sent to stdout vs stderr for situations when one of them is redirected. For example, it is a common practice to redirect the regular output of a console program (stdout) to a file, while expecting the error messages to keep appearing in the console.
It is also possible to redirect stderr to another destination from within a program using the freopen function.
Also, stderr is never fully buffered on startup. It is library-dependent whether the stream is line-buffered or not-buffered by default (see setvbuf).
It is a good practice.
Lets say you use linux. If so, you can run your program following way:
./program >out 2>errout
'out' file will contain only STDOUT.
'errout' file will contain only STDERR
So if your output is hundreds of lines long, it is easier to look for few errors in 'errout' rather than look through tons of non-error lines combined with error lines.
If you redirect your program's output into a file you still would want to see the errors on screen.
In addition to stderr not being buffered, it is also nice to split output into errors vs. normal output to allow other programs to use of your program more easily. That way, the calling program can redirect standard or error output selectively depending on what it needs to know. This same facility can be used manually through Unix shells - here's one way I use that sometimes:
% find / -iname hello.txt
find: /.DocumentRevisions-V100: Permission denied
find: /.fseventsd: Permission denied
find: /.MobileBackups: Permission denied
find: /.Spotlight-V100: Permission denied
find: /.Trashes: Permission denied
^C
% find / -iname hello.txt 2>/dev/null <-- filter "Permission denied" errors

How to log output of unfinished / non-responding / hanging command in win7?

I want redirect console output of a command.
The thing is the command hangs midway (more or less) and even though it outputs to console the logfile is empty. I have also tried wtee.exe like so: com.exe | %pat%wtee.exe log.txt but it does not work.I need something that dumps the console in realtime.
I'm open to pretty much any solution including c++ and powershell csript etc.
For the record i need it to post some verbose output ( https://superuser.com/questions/564468/how-can-i-store-encfs6-xml-in-another-location-and-still-make-it-detectable )
Thanks in advance
UPDATE:
Wohoo it works.
Apparently i have to delete the logfile before i run the batch script + i had to redirect stderr to stdout before piping to wtee.exe like so:
mycommand.exe 2>&1 | wtee.exe %abspath%log.txt
if i use
mycommand.exe 2>&1 | wtee.exe -a %abspath%log.txt
then i do not have to delete the file every time.
Interesting idea the one with baretail but there is no need for it now. the stream is sent both to the console and to the log file.
Thanks a bunch
UPDATE2: i also used the gnuwin32 tag since tee and wtee are pretty much the same and so this applies to tee.exe, i think!
How exactly does it 'not work'? What happens if you redirect STDOUT and STDERR to a file (command >log.txt 2>&1)? Do you still get output on the console? If so, the command doesn't write to STDOUT, so tee (or wtee for that matter) doesn't get any input, because the pipe connects STDOUT of command with STDIN of tee. In that case try redirecting the handles 3-9 until you find the handle that the command writes to. Example:
command 3>log.txt
You can compensate for the missing console output by displaying the log file in a pager (e.g. baretail).
Once you found the handle you can redirect it to STDOUT and then pipe it into tee:
command 5>&1 | tee log.txt

Batch use of | symbol

What is "|" symbol used for in batch?
Because its not a command I cant use | /? to find out what it does, and if I have something like Stackoverflow|Stackoverflow (as an example) I'm told "stackoverflow is not a recognized as an internal or external command, operable program or batch file"
It's the pipe operator, or redirect operator. From TechNet:
Reads the output from one command and writes it to the input of another command. Also known as a pipe.
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).
The pipe operator | directs (pipes) the output of the first command to the standard input of the second command. So running
somecmd | anothercmd
Would first run somecmd, then gather the output of somecmd and run anothercmd, giving it the output of somecmd as input. You can read about it in innumerable places, just google "pipe command line" or something like it.
This character is used to chain commands.
There's a lot of documentation available on this. Wikipedia is probably a good place to start.

Resources