Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > How to stop perl from exiting when stat($_)->size fails

Reply
Thread Tools

How to stop perl from exiting when stat($_)->size fails

 
 
Peter Juuls
Guest
Posts: n/a
 
      02-15-2006
In my script I fetch the filesize with stat($_)->size from File::stat.
Occasionally it fails although the file exists, and perl exits with this
error on STDERR: Can't call method "size" on an undefined value at
myscript.pl line 7.

I don't want the script to exit, instead I want to ignore the "bad" file and
continue with the next file. I have tried to do tests on file-existence
BEFORE the stat->size is executed, to prevent perl from exiting, but nothing
seems to work.

use File::stat
......
if ((-e $_) && (-r $_) && ($st = stat($_)) {
$bytes = stat($_)->size ;
}

How can I prevent the script from exiting? (ActiveStatePerl587 on
Windows2000)

Thanks
Best regards
Peter Juuls


 
Reply With Quote
 
 
 
 
xhoster@gmail.com
Guest
Posts: n/a
 
      02-15-2006
"Peter Juuls" <(E-Mail Removed)> wrote:
> In my script I fetch the filesize with stat($_)->size from File::stat.
> Occasionally it fails although the file exists, and perl exits with this
> error on STDERR: Can't call method "size" on an undefined value at
> myscript.pl line 7.


If you change it to:
(stat($_) or die $!)->size;
Then at least you will get the real error message.

>
> I don't want the script to exit, instead I want to ignore the "bad" file
> and continue with the next file. I have tried to do tests on
> file-existence BEFORE the stat->size is executed,


You probably have a race condition, where the file exists the first 3 times
you stat it, but not the final time.

> to prevent perl from
> exiting, but nothing seems to work.


If you don't want Perl to exit, don't call the size method on an undefined
value. The easiest way to do that is to check the definedness of the value
before calling the method.

>
> use File::stat
> .....
> if ((-e $_) && (-r $_) && ($st = stat($_)) {
> $bytes = stat($_)->size ;
> }



my $st=stat($_);
if (defined $st) {
$bytes=$st->size;
};


Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
 
 
 
Ian Wilson
Guest
Posts: n/a
 
      02-15-2006
Peter Juuls wrote:
> In my script I fetch the filesize with stat($_)->size from File::stat.
> Occasionally it fails although the file exists, and perl exits with this
> error on STDERR: Can't call method "size" on an undefined value at
> myscript.pl line 7.
>
> I don't want the script to exit, instead I want to ignore the "bad" file and
> continue with the next file. I have tried to do tests on file-existence
> BEFORE the stat->size is executed, to prevent perl from exiting, but nothing
> seems to work.
>
> use File::stat
> .....


I hope "....." means "use Strict; use Warnings;"

> if ((-e $_) && (-r $_) && ($st = stat($_)) {


perldoc File::Stat says
$st = stat($file) or die "No $file: $!";
It looks like you are discarding some useful info.

You could simplify this expression by using fewer parens with a lower
precedence operator and remembering that $_ is a default variable for
many operators. I'd write something like:
if ( -e and -r and ... ) {

Though I'm not certain that readability is a prerequisite for
determinimg the size of a file (is it?)


> $bytes = stat($_)->size ;


Huh? See perldoc File::Stat for the correct usage!

You might end up with:
$bytes = $st->size if <expression>;

> }
>
> How can I prevent the script from exiting? (ActiveStatePerl587 on
> Windows2000)


In general, see
perldoc -f eval


I'd break the expression down into separate statements so that I could
report failures more fully:
"file '$_' does not exist!\n"
"unable to eval stat->size of '$_' because $@"
etc.

I'm unfamiliar with File::Stat and haven't tested the code quoted above,
so caveat emptor. Hopefully it will point you in the right direction.
 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      02-15-2006
Ian Wilson wrote:
> Peter Juuls wrote:
> > In my script I fetch the filesize with stat($_)->size from File::stat.
> > Occasionally it fails although the file exists, and perl exits with this
> > error on STDERR: Can't call method "size" on an undefined value at
> > myscript.pl line 7.
> >
> > I don't want the script to exit, instead I want to ignore the "bad" file and
> > continue with the next file. I have tried to do tests on file-existence
> > BEFORE the stat->size is executed, to prevent perl from exiting, but nothing
> > seems to work.
> >
> > use File::stat
> > .....

>
> I hope "....." means "use Strict; use Warnings;"


I don't, since both of those would give compiler errors in Unix, and
silently do nothing in Windows.

> > $bytes = stat($_)->size ;

>
> Huh? See perldoc File::Stat for the correct usage!


Well, (1) there's no such module, and (2) there's nothing at all wrong
with that usage. What do you think is wrong with it?

> I'm unfamiliar with File::Stat and haven't tested the code quoted above,


Clearly. If you had, you wouldn't have chided the OP for perfectly
valid code. Perhaps you should reconsider that policy in the future.

Paul Lalli

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      02-15-2006
Peter Juuls wrote:
> In my script I fetch the filesize with stat($_)->size from File::stat.
> Occasionally it fails although the file exists, and perl exits with this
> error on STDERR: Can't call method "size" on an undefined value at
> myscript.pl line 7.
>
> I don't want the script to exit, instead I want to ignore the "bad" file and
> continue with the next file. I have tried to do tests on file-existence
> BEFORE the stat->size is executed, to prevent perl from exiting, but nothing
> seems to work.
>
> use File::stat
> .....
> if ((-e $_) && (-r $_) && ($st = stat($_)) {
> $bytes = stat($_)->size ;
> }


Why are you mixing the two distinct ways of using stat?

Try one of:

if (-e $_ and -r _ ) {
$bytes = -s _;
}

or:
use File::stat;
if ($st = stat($_) and $st->mode & 0400) {
$bytes = $st->size;
}

> How can I prevent the script from exiting? (ActiveStatePerl587 on
> Windows2000)


In this case, don't call a method on an undefined value - that is,
check the return value of stat() before you try to use that return
value as an object.

In the general case, if you have code that may fail, wrap it in an
eval{} block, and test $@ afterwords. This is Perl's means of
exception handling.
perldoc -f eval

Paul Lalli

 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      02-15-2006
Ian Wilson <(E-Mail Removed)> wrote in
news:dsvoe6$5q8$(E-Mail Removed)-infra.bt.com:

> Peter Juuls wrote:
>> In my script I fetch the filesize with stat($_)->size from
>> File::stat. Occasionally it fails although the file exists, and perl
>> exits with this error on STDERR: Can't call method "size" on an
>> undefined value at myscript.pl line 7.
>>
>> I don't want the script to exit, instead I want to ignore the "bad"
>> file and continue with the next file. I have tried to do tests on
>> file-existence BEFORE the stat->size is executed, to prevent perl
>> from exiting, but nothing seems to work.
>>
>> use File::stat
>> .....

>
> I hope "....." means "use Strict; use Warnings;"


use strict;
use warnings;

Case matters.

Sinan

--
A. Sinan Unur <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

 
Reply With Quote
 
Peter Juuls
Guest
Posts: n/a
 
      02-15-2006
"Peter Juuls" <(E-Mail Removed)> wrote in message
news:43f35bcd$0$46979$(E-Mail Removed) k...
> I don't want the script to exit, instead I want to ignore the "bad" file
> and
> continue with the next file. I have tried to do tests on file-existence
> BEFORE the stat->size is executed, to prevent perl from exiting, but
> nothing
> seems to work.
>
> How can I prevent the script from exiting? (ActiveStatePerl587 on
> Windows2000)


Thanks for your tips, everyone, I have replaced my old code with this code

use File::stat ;
......
my $st=stat($_);
if (defined $st) {
$bytes=$st->size;
};

This is an improvement, the script no longer exits when stat($_) fails for a
single file. It just skips the "bad" file, and that is what I want.
Still, I don't quite understand why it fails on a valid filename (I DO know
the file exists and is not accessed in other parts of my script or by other
programs), it happens seldomly, though, only once for several millions
files. A tip pointed out that this code gives me the real error message, so
I will use it to get to the bottom of the problem.

(stat($_) or die $!)->size;


Best regards
Peter Juuls


 
Reply With Quote
 
Ian Wilson
Guest
Posts: n/a
 
      02-16-2006
Paul Lalli wrote:
> Ian Wilson wrote:
>
>>Peter Juuls wrote:
>>
>>> $st = stat($_);
>>> $bytes = stat($_)->size ;

>>
>>Huh? See perldoc File::Stat for the correct usage!

>
> Well, <snip> there's nothing at all wrong
> with that usage. What do you think is wrong with it?


I don't see a need to create $st and then throw it away.

From reading perldoc File::Stat I would use $st when invoking the size
method.

my $st = stat($_);
my $bytes = $st->size;

If you are going to invoke stat($_) twice (needlessly), once as part of
a conditional and again to obtain the size, then you should just be able
to do

if (-e and -r and stat($_)) {
my $bytes = stat($_)->size;
}

There's no need to save the results in $st if you never use it.

However the above still looks very 'wrong' to me, it invokes stat twice
needlessly, invokes -e and -r needlessly and discards all sorts of
information that I'd want to know about.

I'd do something like

#!/usr/bin/perl
use strict;
use warnings;
use File::stat;

$_ = 't.pl';

if (my $st = stat($_)) {
print "File $_ has size ", $st->size, " bytes\n";
} else {
die "Cannot stat($_) because $!";
}
 
Reply With Quote
 
Ian Wilson
Guest
Posts: n/a
 
      02-16-2006
Ian Wilson wrote:
> Paul Lalli wrote:
>
>> Ian Wilson wrote:
>>
>>> Peter Juuls wrote:
>>>
>>>> $st = stat($_); $bytes = stat($_)->size ;
>>>
>>>
>>> Huh? See perldoc File::Stat for the correct usage!

>>
>>
>> Well, <snip> there's nothing at all wrong
>> with that usage. What do you think is wrong with it?

>
>
> I don't see a need to create $st and then throw it away.
>
> From reading perldoc File::Stat I would use $st when invoking the size
> method.
>
> my $st = stat($_);
> my $bytes = $st->size;
>
> If you are going to invoke stat($_) twice (needlessly), once as part of
> a conditional and again to obtain the size, then you should just be able
> to do
>
> if (-e and -r and stat($_)) {
> my $bytes = stat($_)->size;
> }
>
> There's no need to save the results in $st if you never use it.
>
> However the above still looks very 'wrong' to me, it invokes stat twice
> needlessly, invokes -e and -r needlessly and discards all sorts of
> information that I'd want to know about.
>
> I'd do something like
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use File::stat;
>
> $_ = 't.pl';
>
> if (my $st = stat($_)) {
> print "File $_ has size ", $st->size, " bytes\n";
> } else {
> die "Cannot stat($_) because $!";
> }


I meant warn not die.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
stop script w/o exiting interpreter Alan Isaac Python 6 01-28-2007 01:13 AM
How do I stop Python IDLE (GUI) from immediately exiting when I enter it? John (Z R) L Python 6 11-21-2006 07:17 PM
How can I prevent perl from exiting during a network error? Song Lining Perl Misc 3 05-11-2005 04:39 PM
Re: Stop Python from exiting upon error in Windows Tom Plunket Python 6 07-15-2003 04:26 PM



Advertisments