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

Hello, I am getting following error in my first script.
shell.pl" 59 lines, 1470 characters daahpdev: dev/home/rvaishna$ perl shell.pl Scalar found where operator expected at shell.pl line 46, at end of li +ne (Missing operator before ?) syntax error at shell.pl line 46, near ") $FSUSED " Unmatched right bracket at shell.pl line 59, at end of line syntax error at shell.pl line 59, near "}" Execution of shell.pl aborted due to compilation errors.
And the Script is mentioned below:
$SYS_NAME=`uname -s`; if ($SYS_NAME =~ "AIX") { $SYS_TYPE=1; `/usr/bin/df -k | /usr/bin/sort +6 >$FILE`; } elsif ($SYS_NAME =~ "HP-UX") { $SYS_TYPE=2; `/usr/bin/bdf -i >$FILE`; } elsif ($SYS_NAME =~ "Linux") { $SYS_TYPE=3; `/bin/df -kP >$FILE`; } else { print "Unknown system: $SYS_NAME."; exit -1; } open (DF, $FILE) || die "Can't Open File: $FILE\n"; while (defined ($_ = <DF> )){ ################################################################### +######## # AIX ################################################################### +######## if ($SYS_TYPE == 1){ ($FS, $BLOCKS, $FSFREE, $FSUSED, $IUSED, $PIUSED, $MOUNT) = spli +t; $FSUSED=~s/([0-9])\%/$1/; $PIUSED=~s/([0-9])\%/$1/; } ################################################################### +######## # Every OS ################################################################### +######## if ($MOUNT eq "\/") { $FS = "Root" } elsif ($FS=~/:/) { $FS1 = "NFS from " . $FS; $FS=$FS1 } if ($FSUSED >= 90) $FSUSED = "*$FSUSED*"; } if ($PIUSED > 60) { $PIUSED = "*$PIUSED*"; } if ($BLOCKS ne "Size (MB)") { $BLOCKS /= 1024 }; if ($FSFREE ne "Free (MB)") { $FSFREE = int ($FSFREE /= 1024) }; if ( (not $MOUNT=~"\/u\/") && (not $MOUNT=~"Mounted") || ($FS=~"NFS +") ) { printf "%-38s %-9d %-9d %-7s %-7s %-11s\n",$MOUNT, $BLOCKS, $FSF +REE, $FSUSED, $PIUSED, $FS; } }

Replies are listed 'Best First'.
Re: Newbee to Perl and the error
by ELISHEVA (Prior) on Dec 25, 2010 at 21:09 UTC

    Welcome to Perl Monks and welcome to Perl!

    I think you forget a "{" here:

    if ($FSUSED >= 90) $FSUSED = "*$FSUSED*"; }

    Also, it would be wise to get in the habit of using use strict; use warnings at the top of every script. Although it wouldn't have done anything to help you find this particular bug, it will over time save you much grief. With apologies to Dr. Seuss, here is why The strictures, according to Seuss.

    It is also a very good idea to declare your variables using my or our so Perl can help you identify typos in variable names and control whether or not the variable is visable to scripts and modules other than the current one. In fact, had you used strict and warnings you would have have gotten a host of complaints about undefined variables, like this:

    Although all those warnings can be very annoying, they will help you learn good programming habits. The more you code, the fewer such warnings you will see. In this case the following few lines at the beginning of your program would have allowed your code to compile cleanly even under "use strict; use warnings".

    use strict; use warnings; my $SYS_NAME; my $FILE; my $FS; my $FS1; my $FSUSED; my $PIUSED; my $FSFREE; my $MOUNT; my $SYS_TYPE; my $IUSED; ... rest of your code here...

    A final note. Common programming convention is to reserve all capital variable names for constants. It is best to name normal working variables in lower case and/or mixed camel case, e.g.my $sys_name; my $file; or my $sysName; my $file and so forth.

    Once again, welcome to Perl Monks and to Perl!

Re: Newbee to Perl and the error
by eyepopslikeamosquito (Archbishop) on Dec 26, 2010 at 00:28 UTC

    Since you are new to Perl, I can offer some advice about the code at the top of your script, namely:

    $SYS_NAME=`uname -s`; if ($SYS_NAME =~ "AIX") { $SYS_TYPE=1; `/usr/bin/df -k | /usr/bin/sort +6 >$FILE`; } # ...
    First, I don't see how the $FILE variable is set to a value. Having said that, you probably don't need this variable at all because you can capture the command stdout directly to a Perl variable without bothering to save it to an intermediate file. Second, you can use the Perl built-in $^O variable to determine what system you are running on without needing to run the external uname command. Finally, it is good practice to always check the return code any time you run an external command. To illustrate the above points with some code:
    my @df_stdout; if ($^O =~ /aix/i) { $SYSTYPE=1; @df_stdout = `/usr/bin/df -k | /usr/bin/sort +6`; my $rc = $? >> 8; $rc == 0 or die "error: df command failed, rc=$rc"; } # ... for (@df_stdout) { # Put your while loop body here... }
    Note further that you can replace:
    for (@df_stdout) {
    above with:
    for my $line (@df_stdout) {
    to use an explicit variable ($line) rather than relying on $_.

    As for resources for learning Perl, I suggest you start by visiting learn.perl.org. And, as described in detail above by ELISHEVA, you should start all your scripts with use strict and use warnings.

Re: Newbee to Perl and the error
by morgon (Priest) on Dec 26, 2010 at 01:27 UTC
    A word on style:

    $SYS_TYPE=1; ... if ($SYS_TYPE == 1) {
    Don't do this. It just makes your code hard to read (and to maintain) - this is Perl not C.

    So rather:

    $sys_type = "AIX"; ... if ($sys_type eq "AIX") {
    All-caps are usually used for constants, not for normal variables.

    And when an open fails $! contains the error-message from the OS (which is very useful), so rather than

    open (DF, $FILE) || die "Can't Open File: $FILE\n";
    do it like this:
    open my $df, "<", $file or die "Can't Open File: $file: $!\n
Re: Newbee to Perl and the error
by Anonymous Monk on Dec 25, 2010 at 21:04 UTC
    around line 46 you have
    if ($FSUSED >= 90) $FSUSED = "*$FSUSED*"; }
    you're missing a left brace