<?xml version="1.0" encoding="windows-1252"?>
<node id="976219" title="Re^3: Getting error while executing the script" created="2012-06-14 10:11:35" updated="2012-06-14 10:11:35">
<type id="11">
note</type>
<author id="72516">
blue_cowdawg</author>
<data>
<field name="doctext">
&lt;ul&gt;&lt;ul&gt;&lt;i&gt;

&lt;/i&gt;&lt;/ul&gt;&lt;/ul&gt;
&lt;p&gt;
Where do I begin with this script?  There's all sorts of things wrong with it. 
&lt;/p&gt;
&lt;p&gt; 
First off your script should have the following two pragmas right from the start:
&lt;code&gt;
use strict;
use warnings;
&lt;/code&gt;
this will aid you in troubleshooting your code by forcing you to use proper techniques so far as scoping, etc. etc. etc.
&lt;/p&gt;

&lt;code&gt;
#Checks the type of OS here

$OS = `uname -s`;

print ("The Operating System is $OS");

if ($OS == SunOS ) {
   
   &amp;&lt; snip1 &amp;&lt;
&lt;/code&gt;

&lt;p&gt;
You're missing a few things here...   A rewrite should look like:

&lt;code&gt;
my $os = `uname -s`;   # why capital?
chomp $os;             # get rid of the EOL character, you'll be glad you did.
printf "Operating system: %s\n",$os;
if ( $os eq 'SunOS' ) {    # this is where EOL needs to be gone...

&amp;&lt; snip! &amp;&lt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Next bit of headache:
&lt;code&gt;
$DF = `df -h $FILESYSTEM | grep -v "Filesystem" | sed -e "s/%//g"|
+awk '{print $5}'`;
    
    print ("The file system $ FILESYSTEM usage is $DF % \n");
&lt;/code&gt;
If you are programming in Perl why the h3!! are you invoking grep and awk?  Secondly using &lt;code&gt;df -h&lt;/code&gt; is going to give you "human readable" output and is useless in the context you are trying to use it in namely doing numerical comparisons.  &lt;code&gt;df -k&lt;/code&gt; might make more sense, but a straight up &lt;code&gt;df&lt;/code&gt; is probably what you really need. Since you are picking off the percentage of use that's the only way you are getting away with this.   Try this:
&lt;code&gt;
my $cmd=sprintf("df -k %s |",$FILESYSTEM)  #note the trailing pipe in the format
open PIPE,$cmd or die "$cmd: $!";
my $junk=&lt;PIPE&gt;; # get rid of the first line.. it's junk.
#
#   Could probably use /[\s]+/ but...
my @df=split(/[\s\n\t]+/,&lt;PIPE&gt;)
close PIPE; # done with this.
my $df=$df[4];  #keep in mind the scalar $df is different than the array @df
chomp $df;      # just for grins
$df =~ s/\%//g; # strip the %
printf "File system %s is %d%% used\n",$FILESYSTEM,$df
&lt;/code&gt;

&lt;p&gt;
My next nit to pick:
&lt;code&gt;
$DU = `du -sh $FILESYSTEM | sort -rn | head -20`;
&lt;/code&gt;
I'm not so sure that what you think this is doing is what is really happening.  By doing a &lt;code&gt;du -sh&lt;/code&gt; you are getting a summary of usage &lt;i&gt;for that directory&lt;/i&gt; and not a list of the subdirectories with their usage.  Using the &lt;code&gt;-h&lt;/code&gt; flag also invalidates the numerical sorting you are trying to do.  Here's my rewrite:
&lt;code&gt;


open PIPE, sprintf("du -s %s/* |,$FILESYSTEM) or die $!;
my @raw=&lt;PIPE&gt;;
chomp @raw;
my @summary=();
foreach my $line(@raw){
        my($blocks,$subdir)=split(/[\s+]/,$line);
        push @summary,{
                        blocks=&gt;$blocks,
                        subdir=&gt;$subdir
        };
}

@summary=sort {
                $b-&gt;{blocks} &lt;=&gt; $a-&gt;{blocks}
        } @summary;

printf "%s\n",join("\n",
        map { 
                sprintf("%d\t%s",$_-&gt;{blocks},$_-&gt;{subdir})
        } @summary[0..19]
        );

&lt;/code&gt;
Now I realize I've thrown some advanced stuff at ya, but I'll try and explain what's going on here.  I've opened a pipe to collect the stdout of the command (I'll use /foo for a file system example) &lt;code&gt; du -s /foo/* &lt;/code&gt; and I've slurped it into an array &lt;code&gt;@raw&lt;/code&gt;. I then iterate over that array and create an array of hashes (you'll hopefully see why in a second) where I've hashed the values for the subdirectory path and the number of blocks the subdirectory uses. (Actually it is files and subdirectories)
&lt;/p&gt;
&lt;p&gt;
Next thing I'm doing is sorting on the number of blocks in reverse.  The bit that looks like &lt;code&gt;{ $b-&gt;{blocks} &lt;=&gt; $a-&gt;{blocks} } &lt;/code&gt; is an anonymous sub that governs how the &lt;code&gt;sort&lt;/code&gt; function works. The normal behavior for sort would look like &lt;code&gt;$a cmp $b&lt;/code&gt; which is to say an alphabetic forward sort rather than the numerical reverse sort we are doing.
&lt;/p&gt;
&lt;p&gt;
Here is where things get a bit snazzy and tricky at the same time.  &lt;code&gt;map { } @summary...&lt;/code&gt; iterates over the array passed to it.  The bit about &lt;code&gt;@summary[0..19]&lt;/code&gt; passes an array slice consisting of the first 20 elements in that array. The logic inside the map &lt;code&gt; map { sprintf("%d\t%s",$_-&gt;{blocks},$_-&gt;{subdir})} &lt;/code&gt; is putting the hash back together again and &lt;code&gt;join("\n",...&lt;/code&gt; is taking the array coming out of &lt;code&gt;map&lt;/code&gt; and making one big scalar (string) out of it.
&lt;/p&gt;
&lt;p&gt;
Having said that... just remember that in Perl TIMTOWTDI!
&lt;/p&gt;

&lt;div class="pmsig"&gt;&lt;div class="pmsig-72516"&gt;
&lt;hr&gt;
&lt;font size="-2"&gt;

Peter L. Berghold  -- Unix Professional&lt;br&gt;
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg&lt;br&gt;
&lt;/font&gt;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
975991</field>
<field name="parent_node">
976003</field>
</data>
</node>
