URGENT !! Debug this ksh script !

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 ?




Shweta_SinghAsked:
Who is Participating?
 
MikeOM_DBACommented:

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
 
shmuklerCommented:
first you want to replace print on top with echo.
shell is not awk
0
 
Shweta_SinghAuthor Commented:
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
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
MikeOM_DBACommented:

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
 
Shweta_SinghAuthor Commented:
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
 
Shweta_SinghAuthor Commented:
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
 
Shweta_SinghAuthor Commented:
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
 
ahoffmannCommented:
>         getUsers | sort -rn |\
>
>        awk '{ b=$1" MB" }

should be

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

0
 
MikeOM_DBACommented:

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
 
ahoffmannCommented:
MikeOM_DBA, either use:
  shift
   DIR=$1

or

  DIR=$2

but
  shift
   DIR=$2

needs 3 arguments to work
0
 
MikeOM_DBACommented:

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
 
Shweta_SinghAuthor Commented:
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
 
Shweta_SinghAuthor Commented:
This is how I want it to work :

./options.ksh /appl
uyg     : 68768GB
kulgui  : 876876MB
ihuih   : 869KB
iugui   : 876 bytes
tryt     : 0 bytes
0
 
ahoffmannCommented:
if [ $# -le 0 ]; then
   showDiskUsageForUser
   exit
fi
0
 
Shweta_SinghAuthor Commented:
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
 
ahoffmannCommented:
> .. 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
 
TintinCommented:
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
 
Shweta_SinghAuthor Commented:
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
 
ahoffmannCommented:
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
 
Shweta_SinghAuthor Commented:
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
 
TintinCommented:
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
 
ahoffmannCommented:
> 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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.