Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Where do I begin with this script? There's all sorts of things wrong with it.

First off your script should have the following two pragmas right from the start:

use strict; use warnings;
this will aid you in troubleshooting your code by forcing you to use proper techniques so far as scoping, etc. etc. etc.

#Checks the type of OS here $OS = `uname -s`; print ("The Operating System is $OS"); if ($OS == SunOS ) { &< snip1 &<

You're missing a few things here... A rewrite should look like:

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... &< snip! &<

Next bit of headache:

$DF = `df -h $FILESYSTEM | grep -v "Filesystem" | sed -e "s/%//g"| +awk '{print $5}'`; print ("The file system $ FILESYSTEM usage is $DF % \n");
If you are programming in Perl why the h3!! are you invoking grep and awk? Secondly using df -h 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. df -k might make more sense, but a straight up df 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:
my $cmd=sprintf("df -k %s |",$FILESYSTEM) #note the trailing pipe in +the format open PIPE,$cmd or die "$cmd: $!"; my $junk=<PIPE>; # get rid of the first line.. it's junk. # # Could probably use /[\s]+/ but... my @df=split(/[\s\n\t]+/,<PIPE>) close PIPE; # done with this. my $df=$df[4]; #keep in mind the scalar $df is different than the arr +ay @df chomp $df; # just for grins $df =~ s/\%//g; # strip the % printf "File system %s is %d%% used\n",$FILESYSTEM,$df

My next nit to pick:

$DU = `du -sh $FILESYSTEM | sort -rn | head -20`;
I'm not so sure that what you think this is doing is what is really happening. By doing a du -sh you are getting a summary of usage for that directory and not a list of the subdirectories with their usage. Using the -h flag also invalidates the numerical sorting you are trying to do. Here's my rewrite:
open PIPE, sprintf("du -s %s/* |,$FILESYSTEM) or die $!; my @raw=<PIPE>; chomp @raw; my @summary=(); foreach my $line(@raw){ my($blocks,$subdir)=split(/[\s+]/,$line); push @summary,{ blocks=>$blocks, subdir=>$subdir }; } @summary=sort { $b->{blocks} <=> $a->{blocks} } @summary; printf "%s\n",join("\n", map { sprintf("%d\t%s",$_->{blocks},$_->{subdir}) } @summary[0..19] );
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)  du -s /foo/* and I've slurped it into an array @raw. 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)

Next thing I'm doing is sorting on the number of blocks in reverse. The bit that looks like { $b->{blocks} <=> $a->{blocks} } is an anonymous sub that governs how the sort function works. The normal behavior for sort would look like $a cmp $b which is to say an alphabetic forward sort rather than the numerical reverse sort we are doing.

Here is where things get a bit snazzy and tricky at the same time. map { } @summary... iterates over the array passed to it. The bit about @summary[0..19] passes an array slice consisting of the first 20 elements in that array. The logic inside the map  map { sprintf("%d\t%s",$_->{blocks},$_->{subdir})} is putting the hash back together again and join("\n",... is taking the array coming out of map and making one big scalar (string) out of it.

Having said that... just remember that in Perl TIMTOWTDI!

Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

In reply to Re^3: Getting error while executing the script by blue_cowdawg
in thread Getting error while executing the script by arunkarthick

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others browsing the Monastery: (3)
    As of 2018-05-27 19:52 GMT
    Find Nodes?
      Voting Booth?