Loading ...
Sorry, an error occurred while loading the content.

stat function

Expand Messages
  • Paul.G
    Hi All Been looking at the stat function lately and have written a small bit of code in perl, but having difficulty getting it to work when using a while or
    Message 1 of 5 , Jan 29, 2012
    • 0 Attachment
      Hi All

      Been looking at the stat function lately and have written a small bit of code in perl, but having difficulty getting it to work when using a while or foreach loop.


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


      opendir (DIR, "/home");
      while( my $file = readdir(DIR) ) {
           my $fileattrib = stat($file)->size;
           print "$file $fileattrib \n";
      }
      close DIR;

      I am getting the following error message, can someone tell me why this might be the case.

      Can't call method "size" on an undefined value at ./compare3.pl line 8.

      I believe it is telling me that $file is underfined, but not sure why.

      cheers

      [Non-text portions of this message have been removed]
    • Shawn H Corey
      ... Is your /home a separate partition? If so, then it has a directory called lost+found and you don t have permission to read its stats. The error message you
      Message 2 of 5 , Jan 29, 2012
      • 0 Attachment
        On 12-01-29 04:46 AM, Paul.G wrote:
        > Hi All
        >
        > Been looking at the stat function lately and have written a small bit of
        > code in perl, but having difficulty getting it to work when using a
        > while or foreach loop.
        >
        > #!/usr/bin/perl
        > use strict;
        > use warnings;
        > use File::stat;
        >
        > opendir (DIR, "/home");
        > while( my $file = readdir(DIR) ) {
        > my $fileattrib = stat($file)->size;
        > print "$file $fileattrib \n";
        > }
        > close DIR;
        >
        > I am getting the following error message, can someone tell me why this
        > might be the case.
        >
        > Can't call method "size" on an undefined value at ./compare3.pl line 8.
        >
        > I believe it is telling me that $file is underfined, but not sure why.

        Is your /home a separate partition? If so, then it has a directory
        called lost+found and you don't have permission to read its stats. The
        error message you should be getting is: Permission denied

        Change the opendir to:

        opendir( DIR, '.' );

        to read the current directory and it should work.

        Change your code to:

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

        opendir my $dir_handle, '/home';
        while( my $file = readdir($dir_handle) ) {

        my $fileattrib = -1; # some nonsensical value
        $! = 0; # reset file error message

        eval {
        $fileattrib = stat($file)->size;
        };
        if( $@ ){
        chomp( my $msg = $! || $@ );
        warn "could not stat '$file': $msg\n";
        next;
        }

        print "$file $fileattrib \n";
        }
        close $dir_handle;



        --
        Just my 0.00000002 million dollars worth,
        Shawn

        Programming is as much about organization and communication
        as it is about coding.

        Strength is not a measure of the body.
        It's a measure of the heart.
      • Shawn H Corey
        ... Oops, got distracted by the wrong error. Try this instead: #!/usr/bin/perl use strict; use warnings; use File::stat; my $dir = /home ; opendir( my
        Message 3 of 5 , Jan 29, 2012
        • 0 Attachment
          On 12-01-29 04:46 AM, Paul.G wrote:
          > Hi All
          >
          > Been looking at the stat function lately and have written a small bit of
          > code in perl, but having difficulty getting it to work when using a
          > while or foreach loop.
          >
          > #!/usr/bin/perl
          > use strict;
          > use warnings;
          > use File::stat;
          >
          > opendir (DIR, "/home");
          > while( my $file = readdir(DIR) ) {
          > my $fileattrib = stat($file)->size;
          > print "$file $fileattrib \n";
          > }
          > close DIR;
          >
          > I am getting the following error message, can someone tell me why this
          > might be the case.
          >
          > Can't call method "size" on an undefined value at ./compare3.pl line 8.
          >
          > I believe it is telling me that $file is underfined, but not sure why.
          >
          > cheers

          Oops, got distracted by the wrong error. Try this instead:

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

          my $dir = '/home';

          opendir( my $dir_handle, $dir );
          while( my $file = readdir($dir_handle) ) {
          my $fileattrib = stat( "$dir/$file" )->size;
          print "$file $fileattrib \n";
          }
          close $dir_handle;

          When you do the stat, you have to use the full path to the file. Your
          version was trying to file /home files in the current directory.


          --
          Just my 0.00000002 million dollars worth,
          Shawn

          Programming is as much about organization and communication
          as it is about coding.

          Strength is not a measure of the body.
          It's a measure of the heart.
        • David Precious
          On Sun, 29 Jan 2012 01:46:43 -0800 (PST) ... [...] ... The stat() call returned undef. If you print the value of $file within the loop, you ll see why;
          Message 4 of 5 , Jan 29, 2012
          • 0 Attachment
            On Sun, 29 Jan 2012 01:46:43 -0800 (PST)
            "Paul.G" <medura43@...> wrote:

            > Hi All
            >
            > Been looking at the stat function lately and have written a small bit
            > of code in perl, but having difficulty getting it to work when
            > using a while or foreach loop.
            >
            [...]
            > opendir (DIR, "/home");
            > while( my $file = readdir(DIR) ) {
            >      my $fileattrib = stat($file)->size;
            >      print "$file $fileattrib \n";
            > }
            > close DIR;
            >
            > I am getting the following error message, can someone tell me why
            > this might be the case.
            >
            > Can't call method "size" on an undefined value at ./compare3.pl line
            > 8.

            The stat() call returned undef. If you print the value of $file within
            the loop, you'll see why; readdir() returns the name of the files in
            the dir, but as you're not currently in '/home', you'll be looking for
            the file/dir named within whatever your current directory is. (You
            also didn't check for errors in the opendir call.)

            Say something like:

            my $dir = "/home';
            opendir(my $dh, $dir)
            or die "Failed to open $dir - $!";
            while (my $entry = readdir($dh)) {
            next if $entry eq '.' || $entry eq '..';

            if (my $st = stat("$dir/$entry")) {
            my $size = $st->size;
            print "$dir/$entry : $size\n";
            } else {
            warn "Can't stat $dir/$entry";
            }
            }

            Also, you might want to consider looking at File::Find or
            File::Find::Rule for another way to get a list of what you're looking
            for.

            Finally, it appears that you may be trying to find out the total size
            of each user's home directory; if so, stat'ing the dirs will not do
            what you want; it will give you the size occupied by that directory
            entry, not by the contents of the directory. If that's what you're
            after, the Unix "du" command is a good tool for that :)



            > I believe it is telling me that $file is underfined, but not sure why.

            The simple way to find out would have been to print the content of the
            $file variable - either by inserting a print/warn within the loop, or
            stepping through in the debugger and examing the variable at the
            appropriate point.

            A brief example of how you could have used the debugger: start the
            script with the -d flag, to debug:

            [davidp@supernova:~/tmp]$ perl -d paulstat.pl

            Loading DB routines from perl5db.pl version 1.3
            [...]
            main::(paulstat.pl:7): opendir (DIR, "/home");

            ... the debugger stops at that point, showing the first line of code
            it's going to execute, and waiting for input. I want it to stop at
            line 9 (the line with the stat call), so I use "b 9" to set a
            breakpoint at that line, then "r" to run the script:

            DB<1> b 9
            DB<2> r
            main::(paulstat.pl:9): my $fileattrib =
            stat($file)->size;

            ... and it stops there, after printing the line it would execute next.
            At this point, I can use the "x" command to examine the contents of the
            $file var:

            DB<2> x $file;
            0 'davidp'

            ... and there's the contents, confirming the problem.


            Hope that helps make future debugging a little easier! (For simple
            cases like this, a lot of beginners find it easier to add print
            statements to the script rather than playing with the debugger; use
            whatever works for you, but learning rudimentary debugger usage will
            pay off in the long run.)

            Cheers

            Dave P


            --
            David Precious ("bigpresh") <davidp@...>
            http://www.preshweb.co.uk/ www.preshweb.co.uk/twitter
            www.preshweb.co.uk/linkedin www.preshweb.co.uk/facebook
            www.preshweb.co.uk/cpan www.preshweb.co.uk/github
          • Paul.G
            Thank you everybody for your help. I am currently looking at everybodies response however, Shaun I think answered my particular question. cheers
            Message 5 of 5 , Feb 2, 2012
            • 0 Attachment
              Thank you everybody for your help. I am currently looking at everybodies response however, Shaun I think answered my particular question.

              cheers



              ________________________________
              From: Shawn H Corey <shawnhcorey@...>
              To: perl-beginner@yahoogroups.com
              Sent: Sunday, 29 January 2012 11:30 PM
              Subject: Re: [PBML] stat function


               
              On 12-01-29 04:46 AM, Paul.G wrote:
              > Hi All
              >
              > Been looking at the stat function lately and have written a small bit of
              > code in perl, but having difficulty getting it to work when using a
              > while or foreach loop.
              >
              > #!/usr/bin/perl
              > use strict;
              > use warnings;
              > use File::stat;
              >
              > opendir (DIR, "/home");
              > while( my $file = readdir(DIR) ) {
              > my $fileattrib = stat($file)->size;
              > print "$file $fileattrib \n";
              > }
              > close DIR;
              >
              > I am getting the following error message, can someone tell me why this
              > might be the case.
              >
              > Can't call method "size" on an undefined value at ./compare3.pl line 8.
              >
              > I believe it is telling me that $file is underfined, but not sure why.
              >
              > cheers

              Oops, got distracted by the wrong error. Try this instead:

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

              my $dir = '/home';

              opendir( my $dir_handle, $dir );
              while( my $file = readdir($dir_handle) ) {
              my $fileattrib = stat( "$dir/$file" )->size;
              print "$file $fileattrib \n";
              }
              close $dir_handle;

              When you do the stat, you have to use the full path to the file. Your
              version was trying to file /home files in the current directory.

              --
              Just my 0.00000002 million dollars worth,
              Shawn

              Programming is as much about organization and communication
              as it is about coding.

              Strength is not a measure of the body.
              It's a measure of the heart.



              [Non-text portions of this message have been removed]
            Your message has been successfully submitted and would be delivered to recipients shortly.