On Wed, May 01, 2013 at 04:22:42PM +0200, Manfred Lotz wrote: > Hi there,
Hello, > I have a script where I log stuff to a file and the same time displays > it to stdout using Log4perl. > > Here is a minimal example where I log a command which fails. > > <--------------------snip-------------------------> > #! /usr/bin/perl > > use strict; > use warnings; > > #use autodie; > use Log::Log4perl qw(:easy); > > Log::Log4perl->easy_init( > { level => $DEBUG, file => "> test.log", }, > { level => $DEBUG, file => 'STDOUT', } > ); > > my $cmd = 'uname'; > my $parms = '-f'; # invalid parm > > INFO( "Issuing [$cmd $parms]" ); > open my $fh, '-|', "$cmd $parms 2>&1" or die "open: $!"; > INFO( "$_" ) while <$fh>; > close $fh; > > <--------------------snap-------------------------> > > This works great. Output is like this: > 2013/05/01 16:16:40 Issuing [uname -f] > 2013/05/01 16:16:40 uname: invalid option -- 'f' > 2013/05/01 16:16:40 Try 'uname --help' for more information. > > > However, if I add autodie then I get: > > 2013/05/01 16:16:33 Issuing [uname -f] > 2013/05/01 16:16:33 uname: invalid option -- 'f' > 2013/05/01 16:16:33 Try 'uname --help' for more information. > Can't close(GLOB(0x2554c80)) filehandle: '' at ./test02.pl line 20 > > > close does not fail if the command is ok, e.g. 'uname -a'. Can anybody > explain to me why close fails in the example above? One thing that I know bit me with the 'or die' pattern is that with a pipe if the child process exits with an non-zero exit status then close returns undef, even though there is really no problem "closing the pipe". I had to read the perldoc closely to notice this. So with the 'or die' pattern I had to change it around a little bit, from: close $fh or die "close: $!"; ...to... close $fh or $? != 0 or die "close: $!"; I'm *guessing* that the same thing is biting you, in that when the piped process signals failure the close also signals failure, even though there was no actual error with close, and autodie just follows suit and dies. There's no meaningful errno because no error actually occurred within your process. My conclusion appears to be confirmed with the following one-liners: # This works fine. perl -Mautodie -E 'open my $fh, "-|", "/bin/true"; close $fh;' # This fails with the same error you get. perl -Mautodie -E 'open my $fh, "-|", "/bin/false"; close $fh;' So perhaps this is a bug in autodie, or perhaps you should just not use autodie with close and a pipe... I guess a work around should be to disable it for the close: use autodie; open my $fh, "-|", "/bin/false"; { no autodie qw/close/; close $fh or $? != 0 or die "close: $!"; } Regards, -- Brandon McCaig <bamcc...@gmail.com> <bamcc...@castopulence.org> Castopulence Software <https://www.castopulence.org/> Blog <http://www.bamccaig.com/> perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }. q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.}; tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'
signature.asc
Description: Digital signature