How to Redirect error to pipe not File, eg 2| not 2>

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

How to Redirect error to pipe not File, eg 2| not 2>

#1 Post by alan_b » 30 Apr 2010 08:19

I would like to do this, but it crashes :-

Code: Select all

REG QUERY %REGISTRY_KEY% > NUL 2| FIND " " > NUL

is there a simple fix please ?

This code works, but is clumsy :-

Code: Select all

REG QUERY %REGISTRY_KEY% > NUL 2> TT2.TXT
FIND " " < TT2.TXT > NUL
SET /A GOODERROR=%ERRORLEVEL%
DEL TT2.TXT

The problem is that REG.EXE is STUPID and it sets ERRORLEVEL in an idiotic manner.
It assumes no error if there is any message delivered on stream 1
and disregards error messages which may "simultaneously" occur on stream 2,
hence I direct error messages to TT2.TXT, and FIND gives an accurate ERRORLEVEL,
Then I have to preserve that in GOODERROR for use after I get rid of TT2.TXT

Regards
Alan

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to Redirect error to pipe not File, eg 2| not 2>

#2 Post by aGerman » 30 Apr 2010 11:38

Alan,
I can't see the problem.

Code: Select all

@echo off &setlocal

set REGISTRY_KEY="HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage"
REG QUERY %REGISTRY_KEY%>nul 2>&1
echo %ERRORLEVEL%

set REGISTRY_KEY="HKLM\SYSTEM\CurrentControlSet\Control\Nls\XXXXXXXXXXXXXXX"
REG QUERY %REGISTRY_KEY%>nul 2>&1
echo %ERRORLEVEL%

pause>nul

The output is

Code: Select all

0
1


In which case would you get stdOut and stdErr at the same time? (BTW don't believe that it is possible at all)

But if so, why don't you add the StdErr to StdOut to find a key-word?

Code: Select all

REG QUERY %REGISTRY_KEY% 2>&1|FINDSTR /i /c:"error">NUL

or upside down

Code: Select all

REG QUERY %REGISTRY_KEY% 2>&1|FINDSTR /v /i /c:"error">NUL


Regards
aGerman

alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

Re: How to Redirect error to pipe not File, eg 2| not 2>

#3 Post by alan_b » 30 Apr 2010 15:29

REG.EXE falls over with the key :-
"HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications"

Excerpt of my test code :-

Code: Select all

@ECHO OFF
CALL :R "HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications"
GOTO :EOF

:R
REG QUERY %1 > TT1.TXT 2> TT2.TXT
ECHO ERRORLEVEL = %ERRORLEVEL%
ECHO TT1.TXT {
TYPE TT1.TXT
ECHO }
ECHO TT2.TXT {
TYPE TT2.TXT
ECHO }
PAUSE


Consequence is :-
ERRORLEVEL = 0
TT1.TXT {

! REG.EXE VERSION 3.0

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\CFPLog

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\CFP_Setup_3.0.14.276_XP_Vista_x32

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\CFP_Setup_3.0.22.349_XP_Vista_x32

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\LaunchAp

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\LaunchApp

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\Wbutton
}
TT2.TXT {
Error: Access is denied in the key HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\LaunchAp
Error: Access is denied in the key HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\LaunchApp
Error: Access is denied in the key HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\Wbutton
}
Press any key to continue . . .


i.e. REG.EXE tells me of accessible subkeys etc in the console stream, and therefore ERRORLEVEL is made zero,
even though the error stream tells me about subkeys etc to which I have no access.

My original solution was to search for the key phrase "unable to find".
That was a perfect solution for dealing with registry keys that prevented a Comodo Security upgrade, until a German tried to use it, and error/status messages are horribly different to English.
I was aware of that problem before I coded it, but decided it was no problem because I had already learnt that C:\Documents and Settings\etc etc is different in the German O.S.
and assumed all the registry keys would similarly be different - wrong assumption.

Regards
Alan

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to Redirect error to pipe not File, eg 2| not 2>

#4 Post by aGerman » 30 Apr 2010 17:13

Hello Alan,
sry, I had not noticed the access could be denied.

Unfortunately I don't know a possibility to redirect the stdErr to stdIn. The pipe is only for stdOut to stdIn. :(
So probably you have to merge stdOut and stdErr and find a way to separate it using key words and/or RegEx.

Code: Select all

@ECHO OFF
CALL :R "HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications"
GOTO :EOF

:R
REG QUERY %1 >NUL 2>&1
ECHO ERRORLEVEL1 = %ERRORLEVEL%

REG QUERY %1 2>&1|findstr /b /v /c:"!"|findstr /r /v /c:"^$"|findstr /b /i /c:"HKEY">nul
ECHO ERRORLEVEL2 = %ERRORLEVEL%

PAUSE

Or maybe this way (can't test it):

Code: Select all

REG QUERY %1 2>&1|findstr /b /i /v "! HKEY"|findstr /r /v /c:"^$"|findstr .>nul


This would also work for a German. But is this a better way? :|

Regards
aGerman

alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

Re: How to Redirect error to pipe not File, eg 2| not 2>

#5 Post by alan_b » 01 May 2010 05:47

Thanks

You confirmed my fear that I could not pipe stdErr results through a filter without first directing through a temp file.

I have now reviewed my project and decided upon a slight tweak to the "English" version.

When upgrading Comodo Security system, obsolete registry keys may need removal.
It is essential that after a "REG DELETE" of a list of over 100 potential registry keys,
a "REG QUERY" must process that list to confirm none of them were stuck,
and produce an exception report of anything that needs manual attention.
Unfortunately %ERRORLEVEL% cannot distinguish between ABSENT and NO ACCESS.
I did an exception report of keys needing manual attention if there was no "unable to find".

I will now commence the script with

Code: Select all

REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\ZAP\/\ZAP >NUL 2>UNABLE.TXT

and will test each key against UNABLE.TXT instead of "unable to find".

If only Windows was not multi-lingual ! !

Regards
Alan

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to Redirect error to pipe not File, eg 2| not 2>

#6 Post by aGerman » 01 May 2010 08:59

Alan

I experimented a lot (because you made me curios :wink: ).
Finally I think I found a way.
>nul -redirects the stdOut to NUL
2>&1 -merges stdErr and stdOut
>nul 2>&1 -in this order it appends stdErr to stdOut, then it redirects both to NUL
So far.

What about
2>&1 >nul :?: :!:

I figured out that this combination redirects stdOut to NUL and after that it appends stdErr to the (empty) stdOut. This should be exactly what you need. Now you are able to pipe it.
1stCommand 2>&1 >nul|2ndCommand

Regards
aGerman

alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

Re: How to Redirect error to pipe not File, eg 2| not 2>

#7 Post by alan_b » 01 May 2010 09:59

Thanks.

A perfect success, most suitable for your post no. 100.

Code: Select all

REG QUERY %1 2>&1 >NUL | FIND " "

That blocked stdOut, and stdErr was able to pass through filter FIND " "

Code: Select all

REG QUERY %1 2>&1 >NUL | FIND "#"

That blocked everything, showing the stdErr could not pass through filter FIND "#",
because '#' was not present in the error message.

(All my previous tests had stdErr bypassing the FIND filter and going straight to screen.

Regards
Alan

Post Reply