Article 5272 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:5272
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!math.ohio-state.edu!cs.utexas.edu!uunet!fmrco!fmrco!asherman
From: asherman@fmrco.com (Aaron Sherman)
Subject: Re: determining available disk space
In-Reply-To: jeff@rtr.com's message of Fri, 20 Aug 1993 11:29:43 GMT
Message-ID: <ASHERMAN.93Aug24143015@uboat.fmrco.com>
Sender: news@fmrco.uucp
Organization: I-Kinetics, 19 Bishop-Allen Dr., Cambridge, MA
References: <1993Aug20.112943.26545@rtr.com>
Date: Tue, 24 Aug 1993 19:30:15 GMT
Lines: 157


>>>>> jeff@rtr.com (Jeff Moskow) said:

jeff> Is there any machine independent way of determining the about of
jeff> available disk space on a particular partition?  Basically, I
jeff> want to know if I have enough space to complete an operation
jeff> before I begin.  I can certainly execute a df and parse the
jeff> results, but this requires additional code for each new system
jeff> that the script will support.  Am I missing something?

Well, I can offer the following.

This is a script which parses df output on Suns, and if we get enough
people to get it to work on their systems, then we will have a
general-purpose program.

I call this dfscan, and it works in a similar fashion to printf, et
al. To use it, you just need to execute dfscan with a format string,
and any arguments that you want passed on to df. So, to find out how
much space is used on /usr, just type "dfscan %c /usr".


			-AJS

#!/usr/local/bin/perl
#
# Scan output of df and provide it via command-line options
# By Aaron Sherman (I-Kinetics, Inc.), 1993
#
# $Id$

$0	=~ s/^.*\///;
$usage	=  "Usage: $0 [-f <file>] [-h <hostname>] [--]
	<format> [<df options>]\n";
$file	= undef;
$format	= undef;
%mapping= (			# Mapping of format letter to field number
	    'f',0,		# Filesystem
	    't',1,		# Total space
	    'u',2,		# Space used
	    'a',3,		# Space available
	    'c',4,		# Capacity
	    'p',4,		# Percent (same as c)
	    'm',5,		# Mount-point
	    'h',6,		# Host
	    's',6		# Server (same as h)
	    );
$host	= `hostname`;
chop($host);

while(defined($arg = shift))
{
    if ($arg =~ s/^-//)
    {
	if ($arg eq 'f')	# File to read for df output
	{
	    die $usage unless(defined($file = shift));
	}
	elsif ($arg eq 'h')	# Host name
	{
	    die $usage unless(defined($host = shift));
	}
	elsif ($arg eq '-')	# End argument processing
	{
	    die $usage unless(defined($format = shift));
	    last;
	}
	else
	{
	    die $usage;
	}
    }
    else
    {
	$format = $arg;
	last;
    }
}

die $usage unless(defined($format));

@options = @ARGV;

if (defined($file))
{
    open(IN,"<$file") || die("$0: Cannot open \"$file\": $!\n");
}
else
{
    $cmd = 'df '.join(' ',@options);
    open(IN,"$cmd |") || die("$0: Cannot fork: $!\n");
}

while(<IN>)
{
    chop;

    next if (/^File/);		# Header

    if ($cont ne '')		# Continued lines
    {
	substr($_,0,0) = $cont;
	$cont = '';
    }
    else
    {
	if (/^\S+\s*$/)
	{
	    $cont = $_;
	    next;
	}
    }

    die "$0: Unexpected df output on line $.\n"
	unless((@fields = split(/\s+/,$_)) == 6);
    if ($fields[0] =~ /^(\S+):/)
    {
	push(@fields,$1);
    }
    else
    {
	push(@fields,$host);
    }
    $fields[4] =~ s/\%$//;

    &out($format,@fields);
}

exit 0;

sub out
{
    local($output,@f) = @_;
    local($i,$m);

    $output =~ s/\%(.)/($1 eq "%")?"%":&form($1,@f)/eg;
    print $@ if $@;
    print $output, "\n";
}

sub form
{
    local($c,@f) = @_;

    unless (defined($mapping{$c}))
    {
	die "$0: No mapping for \"\%$c\".\n";
    }
    $f[$mapping{$c}];
}
__END__
--
Aaron Sherman			I-Kinetics, Inc.
Systems Engineer		  "Open Systems Stepstones"
Voice: (617)661-8181		19 Bishop Allen Dr.
Fax:   (617)661-8625		Cambridge, MA 02139
Pager: (508)545-0584		asherman@i-kinetics.com