Perl, Pipes and error return codes
Perl, Pipes and error return codes
am 14.08.2007 04:38:23 von Neil Cherry
I need to run an external script and have its output displayed to
the user while running. No problem something like this works fine:
open(IN, "cat file|");
while() {
print ;
}
close IN;
But what if cat returns an error in the middle of cat'ng the file? I
know I can catch the broken pipe (which I'd better catch anyway) but
that doesn't tell me the error returned by cat. How do I figure that
out inside the perl code? I've done some searching but 'perl pipe
error return' mostly get me broken pipe errors. I'm currently trying
to avoid fork, files, while loops of the file, etc as that seems a
little untidy (OK, and I'm also lazy :-).
Thanks
--
Linux Home Automation Neil Cherry ncherry@linuxha.com
http://www.linuxha.com/ Main site
http://linuxha.blogspot.com/ My HA Blog
Author of: Linux Smart Homes For Dummies
Re: Perl, Pipes and error return codes
am 14.08.2007 06:28:33 von xhoster
ncherry@comcast.net wrote:
> I need to run an external script and have its output displayed to
> the user while running. No problem something like this works fine:
>
> open(IN, "cat file|");
> while() {
> print ;
> }
> close IN;
>
> But what if cat returns an error in the middle of cat'ng the file?
Then cat will probably print a message to stderr. Also, "close IN" will
return false and $! and $? will be set accordingly. See the
"If the file handle came from a piped open" section of perldoc -f close.
> I
> know I can catch the broken pipe (which I'd better catch anyway) but
> that doesn't tell me the error returned by cat.
AFAIK, it is the writer (cat in this case) that gets SIGPIPE if the
other side dies, not the reader. The reader just gets an eof.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Re: Perl, Pipes and error return codes
am 14.08.2007 13:13:55 von Paul Lalli
On Aug 13, 10:38 pm, Neil Cherry wrote:
> I need to run an external script and have its output displayed to
> the user while running. No problem something like this works fine:
>
> open(IN, "cat file|");
> while() {
> print ;
> }
>
> close IN;
Please explain to me why you would open a pipe to cat, which does
nothing but output the contents of the file, rather than simply
opening the file itself.
open(IN, '<', 'file');
while () {
print;
}
close IN;
Paul Lalli
Re: Perl, Pipes and error return codes
am 14.08.2007 14:00:30 von Neil Cherry
On 14 Aug 2007 04:28:33 GMT, xhoster@gmail.com wrote:
> ncherry@comcast.net wrote:
>> I need to run an external script and have its output displayed to
>> the user while running. No problem something like this works fine:
>>
>> open(IN, "cat file|");
>> while() {
>> print ;
>> }
>> close IN;
>>
>> But what if cat returns an error in the middle of cat'ng the file?
>
> Then cat will probably print a message to stderr. Also, "close IN" will
> return false and $! and $? will be set accordingly. See the
> "If the file handle came from a piped open" section of perldoc -f close.
Oh, do the obvious. :-)
>> I
>> know I can catch the broken pipe (which I'd better catch anyway) but
>> that doesn't tell me the error returned by cat.
>
> AFAIK, it is the writer (cat in this case) that gets SIGPIPE if the
> other side dies, not the reader. The reader just gets an eof.
Ah that's good, so I can kill it (user abort) by closing and not have
to hunt down the PID. That should work nicely on a shell script I want
to rewrite in Perl, Excellent!
Big thanks!
--
Linux Home Automation Neil Cherry ncherry@linuxha.com
http://www.linuxha.com/ Main site
http://linuxha.blogspot.com/ My HA Blog
Author of: Linux Smart Homes For Dummies
Re: Perl, Pipes and error return codes
am 14.08.2007 15:11:25 von Neil Cherry
On Tue, 14 Aug 2007 07:00:30 -0500, Neil Cherry wrote:
> On 14 Aug 2007 04:28:33 GMT, xhoster@gmail.com wrote:
>> ncherry@comcast.net wrote:
>>> I need to run an external script and have its output displayed to
>>> the user while running. No problem something like this works fine:
>>>
>>> open(IN, "cat file|");
>>> while() {
>>> print ;
>>> }
>>> close IN;
>>>
>>> But what if cat returns an error in the middle of cat'ng the file?
>>
>> Then cat will probably print a message to stderr. Also, "close IN" will
>> return false and $! and $? will be set accordingly. See the
>> "If the file handle came from a piped open" section of perldoc -f close.
>
> Oh, do the obvious. :-)
One interesting thing, the return codes are in multiples of 256. So an
error 2 from the piped command return 512 not 2.
open(IN, "cat file|") || die "Error on pipe: $! $?";
while() {
print ;
}
close IN || die "Error on close: $! $?";
If 'file' doesn't exist cat returns 1 as an error code. The above
Perl code returns 256 (Error on close: 256 at foo.pl line 5)..
--
Linux Home Automation Neil Cherry ncherry@linuxha.com
http://www.linuxha.com/ Main site
http://linuxha.blogspot.com/ My HA Blog
Author of: Linux Smart Homes For Dummies
Re: Perl, Pipes and error return codes
am 14.08.2007 16:04:07 von Paul Lalli
On Aug 14, 9:11 am, Neil Cherry wrote:
> One interesting thing, the return codes are in multiples of
> 256. So an error 2 from the piped command return 512 not 2.
>
> open(IN, "cat file|") || die "Error on pipe: $! $?";
> while() {
> print ;}
>
> close IN || die "Error on close: $! $?";
>
> If 'file' doesn't exist cat returns 1 as an error code. The above
> Perl code returns 256 (Error on close: 256 at foo.pl line 5)..
perldoc pervar
$CHILD_ERROR
$? The status returned by the last pipe close, backtick
(``) command, successful call to wait() or
waitpid(), or from the system() operator. This is
just the 16-bit status word returned by the wait()
system call (or else is made up to look like it).
Thus, the exit value of the subprocess is really
("$? >> 8"), and "$? & 127" gives which signal, if
any, the process died from, and "$? & 128" reports
whether there was a core dump. (Mnemonic: similar
to sh and ksh.)
Paul Lalli
Re: Perl, Pipes and error return codes
am 14.08.2007 17:10:24 von xhoster
Paul Lalli wrote:
> On Aug 13, 10:38 pm, Neil Cherry wrote:
> > I need to run an external script and have its output displayed to
> > the user while running. No problem something like this works fine:
> >
> > open(IN, "cat file|");
> > while() {
> > print ;
> > }
> >
> > close IN;
>
> Please explain to me why you would open a pipe to cat, which does
> nothing but output the contents of the file, rather than simply
> opening the file itself.
Perhaps because he is reducing the script to simplest possible code that
demonstrates that which he wants to demonstrate, and therefore replaced
My_solution_to_fermats_last_problem_not_implemented_in_perl with cat?
I mean, isn't that what we tell people to do before they post here?
> open(IN, '<', 'file');
> while () {
> print;
> }
> close IN;
That really wouldn't illustrate the very question he is asking about, now
would it?
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Re: Perl, Pipes and error return codes
am 14.08.2007 17:40:12 von Paul Lalli
On Aug 14, 11:10 am, xhos...@gmail.com wrote:
>
> That really wouldn't illustrate the very question he is asking
> about, now would it?
No, it wouldn't. I was honestly wondering why he was using cat to
begin with. If it was to reduce the problem to a postable example,
super. If it was because he thought he *had* to use cat instead of
just reading a file, then I would have liked to correct him.
You'll notice that no where in my post did I accuse him of doing
anything wrong. I merely asked for the reason he was doing it.
Paul Lalli
Re: Perl, Pipes and error return codes
am 14.08.2007 18:51:35 von JT
Neil Cherry wrote:
> On Tue, 14 Aug 2007 07:00:30 -0500, Neil Cherry wrote:
> > On 14 Aug 2007 04:28:33 GMT, xhoster@gmail.com wrote:
> >> ncherry@comcast.net wrote:
> >>> I need to run an external script and have its output displayed to
> >>> the user while running. No problem something like this works fine:
> >>>
> >>> open(IN, "cat file|");
> >>> while() {
> >>> print ;
> >>> }
> >>> close IN;
> >>>
> >>> But what if cat returns an error in the middle of cat'ng the file?
> >>
> >> Then cat will probably print a message to stderr. Also, "close IN" will
> >> return false and $! and $? will be set accordingly. See the
> >> "If the file handle came from a piped open" section of perldoc -f close.
> >
> > Oh, do the obvious. :-)
> One interesting thing, the return codes are in multiples of 256. So an
> error 2 from the piped command return 512 not 2.
That's documented - right shift it by 8 ($? >> 8) to get at the
return code, from the lower 7 bits of the low byte ($? & 127) you
should be able to find out which signal (if any) killed the pro-
gram and $? & 128 tells you if the program produced a core dump.
See also "perldoc perlvar".
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Re: Perl, Pipes and error return codes
am 15.08.2007 04:25:52 von dformosa
On Mon, 13 Aug 2007 21:38:23 -0500, Neil Cherry wrote:
> I need to run an external script and have its output displayed to
> the user while running. No problem something like this works fine:
>
> open(IN, "cat file|");
> while() {
> print ;
>}
> close IN;
>
> But what if cat returns an error in the middle of cat'ng the file?
When you close the file handle the close will return a false value.
You can then examine the contents of $? to find out what happened.
perldoc -f close
Contains the docs.