Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

How to match standard error with @execstr

Aug
124
0
I want to match the output of PsLogList (http://technet.microsoft.com/en-us/sysinternals/bb897544.aspx) for the pattern "No records in System event log on COMPUTER.". If no events of a certain type are found, PsLogList displays something like:
"
PsLoglist v2.71 - local and remote event log viewer
Copyright (C) 2000-2009 Mark Russinovich
Sysinternals - www.sysinternals.com

System log on \\COMPUTER:
No records in System event log on COMPUTER.
"
I tried the following:

iff "%@execstr[psloglist -i 41 -m 30]" =~ ".*No records in System event log on.*" then
echo matches
endiff
Unfortunately, PsLogList echoes "No records in System event log on COMPUTER." to standard error and all my attempts to have execstr merge standard output and error were in vain. Can someone help me with that??

Thorsten
 
What happens if you use ...?
Code:
%@execstr[psloglist -i 41 -m 30 2>&1]
 
Or if you use ...
Code:
%@execstr[(psloglist -i 41 -m 30 2>&1)]

For whatever reason @EXECSTR seems to work more as expected if its command is set up as a command group. This observation has been made in the past.
 
Of course this is not the appropriate answer to your question,
but this is the way I would handle this task:
Code:
>psloglist -i 41 -m 30 |& findstr /i /c:"no records"
No records in System event log on xxxxxxxxx.
 
>echo %?
0
Code:
>psloglist -i 41 -m 30 |& findstr /i /c:"no records" > nul:
iff %? eq 0 then
 echo no records
endiff
 
Of course this is not the appropriate answer to your question,
but this is the way I would handle this task:
[ ... deletion ... ]
Code:
>psloglist -i 41 -m 30 |& findstr /i /c:"no records" > nul:
iff %? eq 0 then
echo no records
endiff

Thanks for the thought, Frank. So for Thorsten's question, try this from a TCC or TCC/LE prompt. The application to the original post is obvious.

Code:
echoerr testme |& grep -q testme && echo matched || echo no match
echoerr testme |& grep -q metoo && echo matched || echo no match

Of course, you gotta have the Unix grep utility. Mine is from http://gnuwin32.sf.net/packages/grep.htm . HTH.

Eric
 
Of course, you gotta have the Unix grep utility. Mine is from http://gnuwin32.sf.net/packages/grep.htm . HTH.
Alternatively, you could replace grep with built-in FFIND /K /V /M /E"pattern" or with Vince's 4UTILS GREPP plugin
Code:
C:\> GREPP /?
Match patterns in a stream
 
GREPP [/I] [/V] pattern [file]
 
/I case-insensitive
/V reverse - print on non-match
 
pattern "quoted" if containing whitespace
 
file if missing, redirected/piped input expected
 
@ALL: the solutions from Charles Dye ("2>&1") and Steve Fabian ("(2>&1)") did not work.

At the moment I'm using "psloglist ... |! set nolines=%@lines[CON]" and then "if %nolines"... , but I will try the "|& ffind" solution...
 
There is definitely something wrong with FFIND:
Code:
> psloglist -i 41,1001,6008 -f ue -m 30 |& ffind /t"No records in System event log on"

---- CON
No records in System event log on hombre.

1 line in 1 file

> echo %_ffind_matches
0
 
> psloglist -i 41,1001,6008 -f ue |& ffind /t"No records in System event log on"

0 lines in 0 files

> echo %_ffind_matches
0

Same goes for %? and %_? (latest TCC 14)
 
There is definitely something wrong with FFIND:
Code:
> psloglist -i 41,1001,6008 -f ue -m 30 |& ffind /t"No records in System event log on"
 
---- CON
No records in System event log on hombre.
 
1 line in 1 file
 
> echo %_ffind_matches
0
 
> psloglist -i 41,1001,6008 -f ue |& ffind /t"No records in System event log on"
 
0 lines in 0 files
 
> echo %_ffind_matches
0

Same goes for %? and %_? (latest TCC 14)
Thorsten, I don't believe there's anything wrong with FFIND in TCC, except that maybe those internal variables don't work the way we think they do.

First, one can visually see how normal pipes read from standard input (stdin), not standard error (stderr), by running the following test under TCC or TCC/LE:
Code:
( echo one & echoerr two ) | type /L

The built-in TYPE command will put a line number, via the /L switch, on whatever comes to it from stdin, but not from stderr. And as a reminder, ECHO sends to stdout, but on the opposite side of the pipe, it becomes stdin.

Second, one can see that the syntax "|&" transforms stderr to stdin, as follows:
Code:
( echo one & echoerr two) |& type /L

Third, the presence of those three "internal variables" (%_ffind_matches, %_ffind_files, %_ffind_errors) is news to me, but the description in the TCmd help file makes me wonder if those variables perhaps are only active under certain conditions. I can't seem to use them myself! So, maybe you're on to something, or maybe those values are not accessible after FFIND exits (in which case, why tell us about them?), or maybe they are only active for FTP or IFTP actions.

Finally, I think you can do what you want with the Windows "FINDSTR" command, as follows:
Code:
psloglist -switches args |& findstr "no records" >NUL && echo No matches || echo Matches found

This command line works because FINDSTR, like GREP, sets exit code 0 if matches are found, and exit code 1 if no matches were found. FFIND doesn't handle the exit code that way.

Just some friendly thoughts. HTH.

Eric
 
There is definitely something wrong with FFIND:
Code:
> psloglist -i 41,1001,6008 -f ue -m 30 |& ffind /t"No records in System event log on"
 
---- CON
No records in System event log on hombre.
 
1 line in 1 file
 
> echo %_ffind_matches
0
 
> psloglist -i 41,1001,6008 -f ue |& ffind /t"No records in System event log on"
 
0 lines in 0 files
 
> echo %_ffind_matches
0

Same goes for %? and %_? (latest TCC 14)

The issue is very simple. FFIND on the right side of a pipe is executed in a different instance of TCC than the command prompt. Within that instance the %_ffind _... %? and %_? internal variables exist and can be examined. Once the pipe exits - at the end of the command line - they no longer exist! You must examine them INSIDE the pipe! Try the command below:

Code:
> psloglist -i 41,1001,6008 -f ue -m 30 |& (ffind /t"No records in System event log on" %+ echo %_ffind_matches)
 
Steve wrote:
FFIND on the right side of a pipe is executed in a different instance of TCC than the command prompt. Within that instance the %_ffind _... %? and %_? internal variables exist and can be examined. Once the pipe exits - at the end of the command line - they no longer exist! You must examine them INSIDE the pipe! Try the command below:

Code:
> psloglist -i 41,1001,6008 -f ue -m 30 |& (ffind /t"No records in System event log on" %+ echo %_ffind_matches)
I do not get the same results. Look that this screen dump from my system. The command line has been simplified for demonstration purposes.
Code:
[TCC]$ ver /r
 
TCC  12.11.73  Windows XP [Version 5.1.2600]
TCC Build 73  Windows XP Build 2600  Service Pack 3
Registered to Eric Pement - 1 System License
 
[TCC]$ echo abc | ( ffind /km /T"ab" %+ echo %_ffind_matches matched )
abc
matched
 
[TCC]$
Parentheses do not preserve the variable %_ffind_matches on the right side of the pipe. Steve, can you show me a code sample, with output, where it works as you describe? Thanks.

Eric
 
1/ Nothing can transfer ordinary environment variables from one TCC process to another. They are unique to each instance. You can save them into an entity that is not unique to each process, e.g., files, global aliases or registry variables, and retrieve them from any other process.

2/ Every TCC internal variable is the result of a TCC internal operation, generated dynamically when requested, by the specific TCC process in which it is used.

3/ The category of internal variables summarizing the operation of each command, e.g., _ffind_matches, were not available before version 13. Since names of internal variables are legal environment variable names, the value of an undefined i.v. is the empty string (as it was from PC-DOS 1.0). Your example used an earlier version of TCC, hence the

My example displays the number of matches, using TCC13 or later. Is does NOT to make it available in the original (left of pipe) process.

In-Process Pipes
Since V10 of TCC (but not in TCC/LE) the |! symbol has been available for in-process pipes. Read the whole description!
 
@PSET in Vince's SYSUTILS plugin can create/set an environment variable, so the downstream process of a pipe can affect its upstream parent provided that it has sufficient rights
Code:
C:\>ver & plugin /i sysutils | tail /N1 & SYSHELP @PSET
 
TCC 14.00.29 Windows 7 [Version 6.1.7601]
Version: 11.0 Build 6
@PSET[pid,var[=[value]]]

get[unset[set]] variable in process <pid>

returns value (get/set) or var (unset) on success, else an empty string

C:\>unset /q x & echo match | `(ffind /T"match" & echo %@PSET[%_ppid,x=%_ffind_matches])`
 
---- CON
match
 
1 line in 1 file
1
 
C:\>set x
1
 
3/ The category of internal variables summarizing the operation of each command, e.g., _ffind_matches, were not available before version 13.
Steve, thanks for this info. I was testing with TCC v12 and TCC/LE v13 and reading the documentation from v13, and was unaware that these internal variables from FFIND were not available in version 12, nor in TCC/LE. I see that they are available in later versions of TCC, and I appreciate the clarification.

Eric
 
Back
Top