Ronnie has asked for the wisdom of the Perl Monks concerning the following question:

Sorry if this is a really dumb question but the documentation I've found on this subject is a bit sketchy and or beyond my experience. I want to replicate the UNIX (spit) df -k command so that I can monitor the utilisation of certain disc slices. After a bit of investigation I settled on the Filesys::DiskFree module. The problem is I can't get anything out of this script. I would have expected the following code to return a list of disc slices on the supplied disc name -

#!/usr/bin/perl -w # use Filesys::DiskFree; # $disc = '/dev/vx/dsk/var' ; new Filesys::DiskFree ; $handle->avail($disc) ;

I get the error message - Can't call method "avail" on an undefined value. Am I being particularily stupid here? Where do the returned values (if any - and there should be about 12) go to? I'm not very familiar with modules/methods so I won't be offended if this request is treated with disdain as long as my understanding of it improves.

Cheers,the ever so humble Ronnie Cruickshank

20040304 Edit by Corion: Added code tags around code

20040305 Edit by castaway: Changed title from 'Filesys::DiskFree'

Replies are listed 'Best First'.
Re: Problems using Filesys::DiskFree
by Happy-the-monk (Canon) on Mar 04, 2004 at 15:16 UTC
    simply change the line
    new Filesys::DiskFree ;
    to
    $handle = new Filesys::DiskFree;
    as shown in the manual. That's it!
      Sorry if the questioner is even dumber than his question but the example in the documentation works - even on my system. The problem I am encountering is when you stray from the example given and attempt to use the other functions. The following code
      #!/usr/bin/perl -w
      use Filesys::DiskFree;
      $handle = new Filesys::DiskFree ;
      $handle->disks() ;
      -
      - doesn't fail, it just returns nothing, nada etc I thought that the above would return any discs found to the screen. I hope that they are stored in some hash table/array or something. The problem is where to look? Cheers, Ronnie
Re: Problems using Filesys::DiskFree
by talexb (Chancellor) on Mar 04, 2004 at 14:41 UTC

    You probably want to uncomment your definition of which disk you want to check; and you probably want to capture what 'new' returns into a handle so you can all the 'avail' method.

    Check the documentation -- there's probably a short example provided.

    Alex / talexb / Toronto

    Life is short: get busy!

      The comment is on the previous line to the declaration of the disc variable. I have looked at the documentation and to use a very British phrase the words "As much use as a chocolate fireguard" spring to mind. (But that could just as easily be because I'm in dumber than a politician mode! Cheers, Ronnie
Re: Problems using Filesys::DiskFree
by blue_cowdawg (Monsignor) on Mar 04, 2004 at 15:12 UTC

        get the error message - Can't call method "avail" on an undefined value.

    Ronnie,
    To paraphraase the man page for this module:

    #!/usr/bin/perl -w ###################################### use strict; use warnings; use Filesys::DiskFree; my $handle = new Filesys::DiskFree; # ASSIGN HANDLE! $handle->df(); print "The root device is ".$handle->device("/")."\n"; print "It has ".$handle->avail("/")." bytes available\n"; print "It has ".$handle->total("/")." bytes total\n"; print "It has ".$handle->used("/")." bytes used\n";
    Notice the assignment of the variable $handle. This is important. In order to reference something it has to exist. Now when I run the code on my Linux box on my desk at work I get:
    The root device is /dev/hda1 It has 669364224 bytes available It has 9253654528 bytes total It has 8114221056 bytes used

    Hope this helps.


    Peter L. Berghold -- Unix Professional
    Peter at Berghold dot Net
       Dog trainer, dog agility exhibitor, brewer of fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and a good Belgian ale in your chalice.
Re: Filesys::DiskFree (or Filesys::Df)
by grinder (Bishop) on Mar 04, 2004 at 15:20 UTC

    Interesting, I'm not sure if that module has the same lineage as Filesys::Df, but for many years I have had reliable operations with the following:

    use Filesys::Df; for my $filesys ( qw { / /usr /opt /sybase /spooltmp /var /home } ) { my $df = df( $filesys ); next if $df->{used} < 0 or 0 == $df->{user_blocks}; push @df, [ $filesys, $df->{used} / $df->{user_blocks}, $df->{bava +il}*1024 ]; }

    The < 0 was a work-around for some crappy Solaris NFS code that used to return negative numbers on large (>2GB) NFS mounts, it's probably no longer needed.

    I just checked on CPAN: both modules are fairly old (which doesn't mean anything negative!) although Filesys::Df was updated more recently.

    Personally, I'm quite happy with the procedural approach in this case, I don't think that the OO approach is a win here.

Re: Problems using Filesys::DiskFree
by tachyon (Chancellor) on Mar 04, 2004 at 17:43 UTC

    Am I being particularily stupid here?

    Ah yes actually. Where do you define handle?

    #!/usr/bin/perl -w use Filesys::DiskFree; $disc = '/dev/vx/dsk/var'; # get a handle object, you need to assign it to a var! my $hadle = new Filesys::DiskFree; # call a method on handle object but where do the ret vals go? # if you want them you will need to put them into a var! #$handle->avail($disc); # assuming this method returns an array as you suggest my @res = $handle->avail($disc); use Data::Dumper; print Dumper \@res;

    cheers

    tachyon

      Nope! It seems that I'm not the only one that can't get this to work! Funnily enough I have tried returning the output to a variable (List &/or Scalar) and they remain resolutely empty! This module must store the output somewhere and that's the real problem - where? Any ideas? The following code -
      #!/usr/bin/perl -w
      use Filesys::DiskFree;
      $handle = new Filesys::DiskFree ;
      my $count = 0 ;
      $disc = '/dev/vx/dsk/var';
      my $crap = $handle->device($disc) ;
      print "\n\t$crap\n" ;
      when run results in -

      Use of uninitialized value in concatenation (.) or string at acc_filestore_monitor.pl line 8.

      That would be because crap is empty. Trying the disks method returning the results (or so I thought) to an array produced the same error. I'm quite willing to accept that I can be somewhat dim at times but, not being familiar with methods etc to any great degree, I do think that the description of this module and it's use would leave someone with more knowledge on the subject scratching their heads! I'm probably going to use Filesys::Df to perform this function but I would like to get to the bottom of this as I don't like to be defeated in this fashion.
      Cheers Ronnie "currently vanquished" Cruickshank

        This is vitually straight out of the docs. Having read the ten lines of synopsis you have to call it like this which as you see performs as desired. The issue is that the df() method need to be called (it calls df(1) and caches the results) so that most of the other methods have data to work with. When reading those docs substitute Filesys::DiskFree->method() with $handle->method() and you should have no issues:

        [root@devel3 root]# cat diskfree.pl #!/usr/bin/perl use Filesys::DiskFree; $handle = new Filesys::DiskFree; $handle->df(); my $device = $ARGV[0] || "/"; print "The $device device is ".$handle->device($device)."\n"; print "It has ".$handle->avail($device)." bytes available\n"; print "It has ".$handle->total($device)." bytes total\n"; print "It has ".$handle->used($device)." bytes used\n"; [root@devel3 root]# ./diskfree.pl The / device is /dev/sda3 It has 79425527808 bytes available It has 142137049088 bytes total It has 55491371008 bytes used [root@devel3 root]# ./diskfree.pl /boot The /boot device is /dev/sda1 It has 31190016 bytes available It has 47755264 bytes total It has 14099456 bytes used [root@devel3 root]# ./diskfree.pl /dev/sda1 The /dev/sda1 device is /dev/sda1 It has 31190016 bytes available It has 47755264 bytes total It has 14099456 bytes used [root@devel3 root]#

        cheers

        tachyon