1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to match standard error with @execstr

Discussion in 'T&T - Scripting' started by thorsten, Jul 9, 2012.

  1. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    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
     
  2. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,358
    Likes Received:
    39
    What happens if you use ...?
    Code:
    %@execstr[psloglist -i 41 -m 30 2>&1]
     
  3. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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.
     
  4. Frank

    Joined:
    Aug 2, 2011
    Messages:
    258
    Likes Received:
    4
    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
    
     
  5. epement

    Joined:
    Jun 28, 2008
    Messages:
    67
    Likes Received:
    2
    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
     
  6. Stefano Piccardi

    Joined:
    May 31, 2008
    Messages:
    376
    Likes Received:
    2
    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
    
     
  7. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    @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...
     
  8. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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)
     
  9. epement

    Joined:
    Jun 28, 2008
    Messages:
    67
    Likes Received:
    2
    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
     
  10. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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)
    
     
  11. epement

    Joined:
    Jun 28, 2008
    Messages:
    67
    Likes Received:
    2
    Steve wrote:
    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
     
  12. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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!
     
  13. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    Yes, with in-process-pipes it works
     
  14. Stefano Piccardi

    Joined:
    May 31, 2008
    Messages:
    376
    Likes Received:
    2
    @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
    
     
  15. epement

    Joined:
    Jun 28, 2008
    Messages:
    67
    Likes Received:
    2
    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
     

Share This Page