Solved

URGENT !!  Debug this ksh script !

Posted on 2006-07-06
22
902 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
 
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
This video discusses moving either the default database or any database to a new volume.

760 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now