Shweta_Singh
asked on
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 ?
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 ?
ASKER
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
PS: Also:
- you coded printUsage twice and forgot the showDiskUsage function.
- USER is a built-in environment variable set to current login user id.
-
ASKER
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
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
ASKER
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 ???
ASKER
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
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
> getUsers | sort -rn |\
>
> awk '{ b=$1" MB" }
should be
getUsers | sort -rn |\
awk '{ b=$1" MB" }
>
>
> awk '{ b=$1" MB" }
should be
getUsers | sort -rn |\
awk '{ b=$1" MB" }
>
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.
MikeOM_DBA, either use:
shift
DIR=$1
or
DIR=$2
but
shift
DIR=$2
needs 3 arguments to work
shift
DIR=$1
or
DIR=$2
but
shift
DIR=$2
needs 3 arguments to work
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
$
ASKER
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 ??
ASKER
This is how I want it to work :
./options.ksh /appl
uyg : 68768GB
kulgui : 876876MB
ihuih : 869KB
iugui : 876 bytes
tryt : 0 bytes
./options.ksh /appl
uyg : 68768GB
kulgui : 876876MB
ihuih : 869KB
iugui : 876 bytes
tryt : 0 bytes
if [ $# -le 0 ]; then
showDiskUsageForUser
exit
fi
showDiskUsageForUser
exit
fi
ASKER
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
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
> .. 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.
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.
What Unix/Linux flavour are you running this on. There are much easier ways to achieve your results depending on what tools you have.
ASKER
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 ??
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 ??
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.
But you see again, that it is very important that you describe your problem unambigious, best witth examples.
ASKER
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.
./options.ksh /appl
uyg : 68768GB
kulgui : 876876MB
ihuih : 869KB
iugui : 876 bytes
tryt : 0 bytes
no options, only the directory name.
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.
#!/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.
> 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
after your done of the while loop over getopts you simply add something like:
if [ $# -gt 0 ]; then
DIRS="$1"
getUsers();
fi
shell is not awk