Solved

URGENT !!  Debug this ksh script !

Posted on 2006-07-06
22
911 Views
Last Modified: 2013-12-26
I have written a ksh script (options.ksh) that tells me the disk usage for every user in a specific directory that would be passed in as an argument.

printUsage()
{
        print "\nUsage: monitor disk usage for each user in a given directory\n"
        print "        [-h]  : Option. Display the help message. "
        print "        [-u]  : Option. COMING UP !!!!"
        print "        [-l]  : Option. COMING UP !!!!\n\n"

exit 1
}

getUsers()
{
        ls -lsR "${1}" 2>/dev/null | awk '{o[$4]+=$6;}END {for (i in o) print o[i]/1048576, i}'
        exit 1
}

showDiskUsage()
{
        getUsers | sort -rn |\

        awk '{ b=$1" MB" }
                ( $1>=1024 ) { b=$1/1024" GB" }
                ( $1<1 && $1>=.000976 ) { b=$1*1024" KB" }
                ( $1<.00976 ) { b=$1*1048576" bytes" }
                ( print  ": " b }' | awk '/^[a-zA-Z0-9]/ { printf "%-10s %s %s\n", $1, $2,$3 }'

        exit 1
}


showDiskUsageForUser()
{
        showDiskUsage | grep "${USER}" | awk '{print $0}'
        exit 1
}


longList()
{
        ls -lsR "${1}" 2>/dev/null | awk '{print $2, $4, $6, $10}' | grep "${2}" | awk '{print $0}' | awk '/^[l-]/ && NF -eq 10 {print $3, $1, $2, $4}' | sort -rn | more
        exit 1
}



while getopts u:l:h PARAM
do
case $PARAM in

  u) showDiskUsageForUser
       UFLAG=1
       USER=$OPTARG
       ;;

    l) longList
       LFLAG=1
       FEATURE_NAME=$OPTARG
       ;;

    h) printUsage
       ;;

      --) shift
       break
       ;;

    ?) printUsage
       exit -1
       ;;
    esac
done

shift $((OPTIND - 1))


Here is how I would want the output to look like:

./options.ksh /appl
uyg     : 68768GB
kulgui  : 876876MB
ihuih   : 869KB
iugui   : 876 bytes
tryt     : 0 bytes

./options.ksh -u kulgui /appl
 kulgui  : 876876MB

./options.ksh -l kulgui /appl
47035292 -rwxrwxrwx jhull itesisc2.rat.gz
10957732 -rw-rw-r-- kulgui namespace.ns
2744605 -rw-rw-r-- kulgui CS_QMGW_1.loging
2231248 -rwxrwxrwx kulgui itedbea2.rat.gz
2065266 -rw-rw-r-- kulgui ryjgv.outman
1407244 -rw-rw-r-- kulgui rty.datoplk.67576
1013 -rw-rw-r-- kulgui CS.log
305 -rw-rw-r-- kulgui CAP.log
0 -rw-rw-r-- kulgui EvtSrv.msg.7687

./options.ksh -h
        Usage: monitor disk usage for each user in a given directory
        [-h]  : Option. Display the help message.
        [-u]  : Option. COMING UP !!!!
        [-l]  : Option. COMING UP !!!!


THe question is: WHERE AM I WRONG ?
and how can I correct the code ?




0
Comment
Question by:Shweta_Singh
  • 9
  • 6
  • 4
  • +2
22 Comments
 
LVL 1

Expert Comment

by:shmukler
ID: 17053873
first you want to replace print on top with echo.
shell is not awk
0
 

Author Comment

by:Shweta_Singh
ID: 17053945
these thing work on the command line. I made small scripts for every option and it was working fine. Im just wrong somewhere in the organisation somewhere. Never used case satements before.
0
 
LVL 29

Accepted Solution

by:
MikeOM_DBA earned 500 total points
ID: 17054078

1) print is OK -- no need to replace.

2) On you case statement you want to get second parameter before executing function:

#...etc...
case $PARAM in

  u)  UFLAG=1
       USER=$OPTARG
       shift
       DIR=$2
      showDiskUsageForUser
       ;;
#...etc...

0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 17054116

PS: Also:
- you coded printUsage twice and forgot the showDiskUsage function.
- USER is a built-in environment variable set to current login user id.
-
0
 

Author Comment

by:Shweta_Singh
ID: 17054138
can you pls explain me how does this conceptually work ?
I tried defining the functions below the case statements and it didn't recognize the function calls in the case statements.

Also, what is a better method of coding :
To make the function calls in the case satement or to sent variables equal to 1 in the case variables and then use if statement and check the variables. If it's 1, then call the function:  i.e

if [[ UFLAG = 1 ]]
then
  showDiskUsageForUser
fi



0
 

Author Comment

by:Shweta_Singh
ID: 17054243
yea, I forgot to call the showDiskUsage function. I called it below the case statement and it worked. But it, by default, works on the current directory that i'm working on and not the directory that I pass in. Why ???
0
 

Author Comment

by:Shweta_Singh
ID: 17054408
there was a syntax error in showDiskUsage


showDiskUsage()
{
        getUsers | sort -rn |\

        awk '{ b=$1" MB" }
                ( $1>=1024 ) { b=$1/1024" GB" }
                ( $1<1 && $1>=.000976 ) { b=$1*1024" KB" }
                ( $1<.00976 ) { b=$1*1048576" bytes" }
                { print  ": " b }' | awk '/^[a-zA-Z0-9]/ { printf "%-10s %s %s\n", $1, $2,$3 }'

        exit 1
}

I just changed { print  ": " b } from ( print  ": " b }

But again, it dosent' accept the directory argument I pass in
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17056591
>         getUsers | sort -rn |\
>
>        awk '{ b=$1" MB" }

should be

        getUsers | sort -rn |\
        awk '{ b=$1" MB" }

0
 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 17058404

You need to get the directory from the parameters as I suggested:

#...etc...
case $PARAM in

  u)  UFLAG=1
       USER=$OPTARG
       shift
       DIR=$2
      showDiskUsageForUser
       ;;
#...etc...
Notice the shift command.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17059424
MikeOM_DBA, either use:
  shift
   DIR=$1

or

  DIR=$2

but
  shift
   DIR=$2

needs 3 arguments to work
0
 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 17060581

True, and the arguments are:

$ script.ksh -u user /path
+-----------------1-----2

$ cat script.ksh
#!/bin/ksh

printUsage() {
        print "\nUsage: monitor disk usage for each user in a given directory\n"
        print "        [-h]  : Option. Display the help message. "
        print "        [-u]  : Option. COMING UP !!!!"
        print "        [-l]  : Option. COMING UP !!!!\n\n"
}
while getopts u:l:h PARAM
do
case $PARAM in

  u) echo "showDiskUsageForUser"
       UFLAG=1
       USER=$OPTARG
       shift
       DIR=$2
       echo "USER=$USER"
       echo "PATH=$DIR"
       ;;

  l) echo "longList"
#... etc ...
#==== Execution:

$ script.ksh -u usrx /path
showDiskUsageForUser
USER=usrx
PATH=/path
$
0
 

Author Comment

by:Shweta_Singh
ID: 17060644
This method wouldn't get the showDiskUsage function working correct if I call it after the case statement. ie if I want showDiskUsage to be working if no arguments are passed in. What bout this problem ??
0
 

Author Comment

by:Shweta_Singh
ID: 17060650
This is how I want it to work :

./options.ksh /appl
uyg     : 68768GB
kulgui  : 876876MB
ihuih   : 869KB
iugui   : 876 bytes
tryt     : 0 bytes
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17062195
if [ $# -le 0 ]; then
   showDiskUsageForUser
   exit
fi
0
 

Author Comment

by:Shweta_Singh
ID: 17062315
There is one argument being passed: the directory name.

So, I guess the if condition wouldn't be satisfied. Besides what happens with getUsers function ?

getUsers()
{
        ls -lsR "${DIR}" 2>/dev/null | awk '{o[$4]+=$6;}END {for (i in o) print o[i]/1048576, i}'
        exit 1
}

showDiskUsage()
{
        getUsers | sort -rn |\
        awk '{ b=$1" MB" }
                ( $1>=1024 ) { b=$1/1024" GB" }
                ( $1<1 && $1>=.000976 ) { b=$1*1024" KB" }
                ( $1<.00976 ) { b=$1*1048576" bytes" }
                { print $2": "b }' | awk '/^[a-zA-Z0-9]/ { printf "%-10s %s %s\n", $1, $2,$3 }'

        exit 1
}


showDiskUsageForUser()
{
        showDiskUsage | grep "${USER}" | awk '{print $0}'
        exit 1
}


longList()
{
        ls -lsR "${DIR}" 2>/dev/null | awk '{print $2, $4, $6, $10}' | grep "${USER}" | awk '{print $0}' | awk '/^[l-]/ && NF -eq 10 {
print $3, $1, $2, $4}' | sort -rn | awk '{ printf "%-10s %s %s %s\n", $1, $2,$3,$4 }' | more
        exit 1

}



while getopts u:l:h PARAM
do
    case $PARAM in

    u) UFLAG=1
        USER=$OPTARG      
        shift
        DIR=$2
        showDiskUsageForUser
        ;;

    l) LFLAG=1
       USER=$OPTARG
       shift
       DIR=$2
       longList
       ;;

    h) printUsage
       ;;

   --) shift
       break
       ;;

    ?) printUsage
       exit -1
       ;;
    esac
done

shift $((OPTIND - 1))

if [ $# -le 0 ]; then
  showDiskUsage
   exit
fi
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17064159
> .. if I call it after the case statement. ie if I want showDiskUsage to be working if no arguments are passed ..
and now
>  There is one argument being passed: the directory name.

do you realy know what you want to do? I insist on saying: you don't!

Please make a clear concept of what your script should do and how you want it to behave under different conditions, then you can start implementing the script.

I guess your initial question have been answerd several times in this thread. Please close it and open another one for new problems.
0
 
LVL 48

Expert Comment

by:Tintin
ID: 17069646
What Unix/Linux flavour are you running this on.  There are much easier ways to achieve your results depending on what tools you have.
0
 

Author Comment

by:Shweta_Singh
ID: 17082990
ahoffmann,
I used the wrong terminology. Earlier I meant 'no options', but an argument, which was the directory name. How would showDiskUsage work if no arguments are passed ? It would show the disk usage of some DIRECTRY, right ??  
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17083331
well, if you differ options and arguments (where options are arguments itself:)
But you see again, that it is very important that you describe your problem unambigious, best witth examples.
0
 

Author Comment

by:Shweta_Singh
ID: 17083429
well, now do you have any idea of how can I get the following to work:

./options.ksh /appl
uyg     : 68768GB
kulgui  : 876876MB
ihuih   : 869KB
iugui   : 876 bytes
tryt     : 0 bytes

no options, only the directory name.
0
 
LVL 48

Expert Comment

by:Tintin
ID: 17085792
The above example could be trivally done as:

#!/bin/ksh
cd $1
for i in `du -sk|sort -rn|awk '{print $2}'`
do
  du -sh $i
done

Note that the above assumes your version of du supports the -h flag (that's why it's always important to state what Unix/Linux flavour you are using) and the above example has no error checking.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 17088137
> no options, only the directory name.
after your done of the while loop over getopts you simply add something like:

  if [ $# -gt 0 ]; then
     DIRS="$1"
     getUsers();
  fi
0

Featured Post

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
mixString challenge 36 124
Smart Camera scanning and reading information 3 107
Making an alias 7 95
Bartender label printing - switch on and off graphics 3 40
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question