how to capture exit value via pipe

how to capture exit value via pipe

am 18.10.2007 16:50:58 von ku916

I wrote a perl script that would read stdout and parse for particular
set of keywords, if found it will exit with error status.

sample cmd:
> sqlplus user/wrong_password @somesql.sql | perl_filter.pl

perl_filter.pl is my script
since we passed in into sqlplus, perl_filter.pl will
parse the stdout (from sqlplus) and find the keyword (i.e. error) and
exit with non-zero value

but the problem I'm having now is that when the parent command itself
errors out how can perl_filter.pl catch the exit value ($?) viva pipe
like:
> sqlpus user/wrong_password @somesql.sql | perl_filter.pl

since there is no program called sqlpus, it will return non-zero exit
value, but perl_filter.pl would not detect any stdout keyword and it
will just exit and return success (zero) value.

any suggestions would be great help

Thanks

Re: how to capture exit value via pipe

am 18.10.2007 17:51:06 von glex_no-spam

ku916 wrote:
> I wrote a perl script that would read stdout and parse for particular
> set of keywords, if found it will exit with error status.
>
> sample cmd:
>> sqlplus user/wrong_password @somesql.sql | perl_filter.pl
>
> perl_filter.pl is my script
> since we passed in into sqlplus, perl_filter.pl will
> parse the stdout (from sqlplus) and find the keyword (i.e. error) and
> exit with non-zero value
>
> but the problem I'm having now is that when the parent command itself
> errors out how can perl_filter.pl catch the exit value ($?) viva pipe
> like:
>> sqlpus user/wrong_password @somesql.sql | perl_filter.pl
>
> since there is no program called sqlpus, it will return non-zero exit
> value, but perl_filter.pl would not detect any stdout keyword and it
> will just exit and return success (zero) value.
>
> any suggestions would be great help

If there's nothing to read from STDIN, then that could be treated
as an error condition.

Re: how to capture exit value via pipe

am 18.10.2007 20:34:01 von xhoster

ku916 wrote:
> I wrote a perl script that would read stdout and parse for particular
> set of keywords, if found it will exit with error status.
>
> sample cmd:
> > sqlplus user/wrong_password @somesql.sql | perl_filter.pl
>
> perl_filter.pl is my script
> since we passed in into sqlplus, perl_filter.pl will
> parse the stdout (from sqlplus) and find the keyword (i.e. error) and
> exit with non-zero value
>
> but the problem I'm having now is that when the parent command itself
> errors out how can perl_filter.pl catch the exit value ($?) viva pipe
> like:
> > sqlpus user/wrong_password @somesql.sql | perl_filter.pl

It appears that a shell is what is starting sqlpus, and thus it is the
shell's responsibility to deal with the error. If you want Perl to deal
with it, make Perl start the script in the first place:

open my $fh, "-|", 'sqlpus user/wrong_password @somesql.sql'
or do_something_with_errors($!,$?);

Maybe even using the 4 or more argument form of pipe open.

Or you could just assume that if STDIN is empty, then an error occurred,
but that seems like a pretty non-general and/or brittle solution.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: how to capture exit value via pipe

am 18.10.2007 21:05:07 von ku916

what are the "4 or more argument form of pipe open"?

is there no way to grab $? or $PIPIESTATUS in perl? I've tried
something like this (but does not work)

if ( $? != 0 || $PIPESTATUS[0] != 0 )
{
print "caught failed exit status\n";
exit 1;
}
else {
exit 0;
}

Re: how to capture exit value via pipe

am 18.10.2007 21:51:40 von xhoster

ku916 wrote:
> what are the "4 or more argument form of pipe open"?

from perlipc:

Since Perl 5.8.0, you can also use the list form of "open"
for pipes : the syntax

open KID_PS, "-|", "ps", "aux" or die $!;

forks the ps(1) command (without spawning a shell, as
there are more than three arguments to open()), and reads
its standard output via the "KID_PS" filehandle. The cor-
responding syntax to write to command pipes (with "|-" in
place of "-|") is also implemented.



>
> is there no way to grab $? or $PIPIESTATUS in perl?

For $?, yes, *if Perl started the command in the first place*.

I'm not aware of a built-in Perl variable named $PIPESTATUS.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: how to capture exit value via pipe

am 18.10.2007 22:53:58 von ku916

On 18 Oct, 14:34, xhos...@gmail.com wrote:
> ku916 wrote:
> > I wrote a perl script that would read stdout and parse for particular
> > set of keywords, if found it will exit with error status.
>
> > sample cmd:
> > > sqlplus user/wrong_password @somesql.sql | perl_filter.pl
>
> > perl_filter.pl is my script
> > since we passed in into sqlplus, perl_filter.pl will
> > parse the stdout (from sqlplus) and find the keyword (i.e. error) and
> > exit with non-zero value
>
> > but the problem I'm having now is that when the parent command itself
> > errors out how can perl_filter.pl catch the exit value ($?) viva pipe
> > like:
> > > sqlpus user/wrong_password @somesql.sql | perl_filter.pl
>
> It appears that a shell is what is starting sqlpus, and thus it is the
> shell's responsibility to deal with the error. If you want Perl to deal
> with it, make Perl start the script in the first place:
>
> open my $fh, "-|", 'sqlpus user/wrong_password @somesql.sql'
> or do_something_with_errors($!,$?);
>
> Maybe even using the 4 or more argument form of pipe open.
>
> Or you could just assume that if STDIN is empty, then an error occurred,
> but that seems like a pretty non-general and/or brittle solution.
>
> Xho
>
> --
> --------------------http://NewsReader.Com/------------------ --
> The costs of publication of this article were defrayed in part by the
> payment of page charges. This article must therefore be hereby marked
> advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
> this fact.

I've tried grabbing PIPESTATUS inside my perl script but now luck,
why?
if ( $? != 0 || $PIPESTATUS[0] != 0 )
{
print "caught failed exit status\n";
exit 1;
}
else {
exit 0;
}

Re: how to capture exit value via pipe

am 19.10.2007 00:18:17 von xhoster

ku916 wrote:
> On 18 Oct, 14:34, xhos...@gmail.com wrote:

> I've tried grabbing PIPESTATUS inside my perl script but now luck,
> why?
> if ( $? != 0 || $PIPESTATUS[0] != 0 )

If you explain why you think it *should* work, perhaps we can explain
why you are wrong to think that.

Perl DOES NOT HAVE a built-in variable named $PIPESTATUS or @PIPESTATUS,
as you would have found out if you used strict.

$ perl -le 'use strict; print $PIPESTATUS[0]'

Global symbol "@PIPESTATUS" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: how to capture exit value via pipe

am 21.10.2007 13:32:06 von Joe Smith

ku916 wrote:

> but the problem I'm having now is that when the parent command itself
> errors out how can perl_filter.pl catch the exit value ($?) viva pipe
> like:
>> sqlpus user/wrong_password @somesql.sql | perl_filter.pl
>
> since there is no program called sqlpus, it will return non-zero exit
> value, but perl_filter.pl would not detect any stdout keyword and it
> will just exit and return success (zero) value.

Q: In your statement, "since there is no program called sqlpus, it will
return non-zero", what is "it"?

A: "It" is the process that built the pipe that was supposed to connect
the two processes together. In many cases, "it" is /bin/sh.

Also, your first sentence talks about a "parent command", but the example
shows a "preceding command". The parent is what builds the pipe. It
then forks two child processes. The first one is told to run 'sqlplus',
but fails. The parent gets informed that the first child process aborted,
and most likely does not even start 'perl_filter.pl' at all.

If you want to detect this situation, then your program has to be
the parent; it has to put the parts of the pipe together and check
the status.

I wanted to make sure you were clear on this concept before continuing.

You could modify perl_filter.pl so that creates the pipe with sqlplus
and reads from that pipe instead of reading from STDIN. That way you
could properly detect when the sqlplus command doesn't even get started.

-Joe