Tuesday, September 22, 2009

Sample System Monitor Shell Script - Using Options

#!/bin/bash
# sys_monitor2.sh
# Usage: sys_monitor2.sh [-u|-d|-f (D/M)| -c number | -m number]
# Sample system monitor script using options
# Tested under Fedora 9

Invalidoptions()
{
echo "Usage: `basename $0` [OPTIONS]"
echo "OPTIONS:"
echo -e "\t -d for display today's date"
echo -e "\t -u for Logged in users list"
echo -e "\t -f ARG for Disk and Memory Statistics"
echo -e "\t (ARG=D for disk statistics; ARG=M for memory statistics)"
echo -e "\t -c ARG for Top CPU consuming process"
echo -e "\t (ARG=10 means top 10 process)"
echo -e "\t -m ARG for Top Memory consuming process"
echo -e "\t (ARG=10 means top 10 process)"
echo -e "\t Note: Only one option at a time and -f,-c and -m require argument"
exit 1
}

Isnumber()
{
if [ $1 -eq $1 2> /dev/null ]
then
:
else
echo -e "You supplied bad argument, \"$1\" is not a number"
Invalidoptions
fi
}

if [ $# -lt 1 -o $# -gt 2 ]
then
Invalidoptions
fi

if [ $# -eq 1 -a "$1" != "-d" -a "$1" != "-u" -a "$1" != "-f" -a "$1" != "-c" ]
then
Invalidoptions
fi

if [ $# -eq 2 ] && [ "$1" != "-f" -a "$1" != "-c" -a "$1" != "-m" ]
then
Invalidoptions
fi

choice=
top="head -$2"
while getopts udf:c:m: choice
do
case $choice in
d) echo -e " Today's Date: \c"
date +" %d-%h-%Y Time: %T";;
u) echo -e "\tCurrently Logged In Users"
who;;
f)
if [ "$OPTARG" = "D" ]
then
echo -e "\t\tDisk Statistics"
df -h | grep "%"
elif [ "$OPTARG" = "M" ]
then
echo -e "\t Memory Statistics "
free -m | awk 'BEGIN{printf "\t\tTotal\tUsed\tFree\n"; OFS="\t" }\
/Mem/||/Swap/{printf "\t"; print $1,$2,$3,$4}'
else
Invalidoptions
fi;;
m) Isnumber $OPTARG
k3sort="sort -nr -k 3"
echo -e " PID PPID MEM CPU COMMAND "
ps -Ao pid= -o ppid= -o pmem= -o pcpu= -o comm=|$k3sort|$top;;
c) Isnumber $OPTARG
k4sort="sort -nr -k 4"
echo -e " PID PPID MEM CPU COMMAND "
ps -Ao pid= -o ppid= -o pmem= -o pcpu= -o comm=|$k4sort|$top;;

esac
done
Output:
[root@localhost blog]# sh sys_monitor2.sh -u
Currently Logged In Users
root tty7 2009-09-23 13:48 (:0)
root pts/2 2009-09-23 14:36 (:0.0)

[root@localhost blog]# sh sys_monitor2.sh -d
Todays Date: 23-Sep-2009 Time: 16:50:38

[root@localhost blog]# sh sys_monitor2.sh -m 5
PID PPID MEM CPU COMMAND
3122 3102 9.6 3.0 firefox
2765 2540 1.9 0.0 nautilus
3849 1 1.7 1.0 ktorrent
2882 1 1.6 0.0 tomboy
2810 1 1.6 0.0 /usr/bin/sealer

[root@localhost blog]# sh sys_monitor2.sh -m
Usage: sys_monitor2.sh [OPTIONS]
OPTIONS:
-d for display today's date
-u for Logged in users list
-f ARG for Disk and Memory Statistics
(ARG=D for disk statistics; ARG=M for memory statistics)
-c ARG for Top CPU consuming process
(ARG=10 means top 10 process)
-m ARG for Top Memory consuming process
(ARG=10 means top 10 process)
Note: Only one option at a time and -f,-c and -m require argument

Sample System Monitor Shell Script -Menu Based


#!/bin/bash
# sys_monitor.sh
# Sample system monitor script using menu
# Tested under Fedora 9
#
# Create the following menu and clear the screen each time it appears
#

clear
echo -e "\033[1m `uname -or` Monitor script\033[0m"
items=" 1.Date
2.Current Users
3.Disk Statistics
4.Memory Statistics
5.Top 10 Memory consuming process
6.Top 10 CPU consuming process
7.Exit"

exit_function()
{
clear
exit
}

#function enter is used to go back to menu and clear screen

enter()
{
ans=
echo ""
echo -e "Do you want to continue(y/n):\c"
stty -icanon min 0 time 0
# When -icanon is set then one character has been received.
# min 0 means that read should read 0 characters.
# time 0 ensures that read is terminated the moment one character is hit.

while [ -z "$ans" ]
do
read ans
done
#The while loop ensures that so long as at least one character is not received
# "read" continue to get executed

if [ "$ans" = "y" -o "$ans" = "Y" ]
then
stty sane # Restoring terminal settings
clear
else
stty sane
exit_function
fi
}

choice=
h10="head -10"
while true
do
echo -e "\n\t PROGRAM MENU \n"
echo -e "$items \n"
echo -n "Enter your choice :"
read choice
case $choice in
1) clear; echo -e "\n\n\t\t Today's Date \n"
date +" %d-%h-%Y Time %T"; enter;;
2) clear; echo -e "\n\n\t\t Currently Logged In Users\n"
who; enter;;
3) clear; echo -e "\n\n\t\t Disk Statistics\n"
df -h | grep "%"
enter;;
4) clear; echo -e "\n\n\t\t Memory Statistics\n "
free -m | awk 'BEGIN{printf "\t\tTotal\tUsed\tFree\n\n"; OFS="\t" }\
/Mem/||/Swap/{printf "\t"; print $1,$2,$3,$4}'
enter;;
5) clear
k3sort="sort -nr -k 3"
echo -e "\033[1m PID PPID MEM CPU COMMAND \033[0m "
ps -Ao pid= -o ppid= -o pmem= -o pcpu= -o comm=|$k3sort|$h10
enter;;
6) clear
k4sort="sort -nr -k 4"
echo -e "\033[1m PID PPID MEM CPU COMMAND \033[0m"
ps -Ao pid= -o ppid= -o pmem= -o pcpu= -o comm=|$k4sort|$h10
enter;;
7)exit_function ;;
*)echo -e "You entered wrong option \n Please enter 1,2,3,4,5,6 or 7\n"
echo " Press enter to continue"
read
clear
esac
done

Output:
2.6.25-14.fc9.i686 GNU/Linux Monitor script
PROGRAM MENU

1.Date
2.Current Users
3.Disk Statistics
4.Memory Statistics
5.Top 10 memory cosuming process
6.Top 10 CPU consuming process
7.Exit

Enter your choice :5
PID PPID MEM CPU COMMAND
3122 3102 9.2 2.6 firefox
2765 2540 1.9 0.0 nautilus
3849 1 1.7 1.0 ktorrent
2882 1 1.6 0.0 tomboy
2810 1 1.6 0.0 /usr/bin/sealer
4041 1 1.4 0.1 gnome-terminal
2394 2393 1.4 1.8 Xorg
2759 2540 1.2 0.0 gnome-panel
2876 1 0.9 0.0 clock-applet
2870 1 0.9 0.0 mixer_applet2

Do you want to continue(y/n):

Saturday, September 19, 2009

Bash Script to check after every one minute whether a user has logged in or not


#!/bin/bash
# isuserloggedin.sh
# Usage: isuserloggedin.sh username
# Shell script which checks after every one minute whether a user has logged in
# or not
# You can also run script in background using & then foreground it to view result

if [ $# -ne 1 ]
then
echo "You supplied wrong arguments"
echo "usage : `basename $0` username"
exit 1
fi

isuserexist()
{
grep -w "$1" /etc/passwd > /dev/null

if [ $? -eq 1 ]
then
echo "$1 is not a valid user"
exit 1
fi
}

isuserexist $1
time=0
while true
do
# you can replace following two statements with
# if `who|grep $1 > /dev/null`
who|grep $1 > /dev/null
if [ $? -eq 0 ]
then
echo "User $1 is logged in "
if [ $time -gt 60 ]
then
hours=$((time/60))
minutes=$((time%60))
echo "He is logged in $hours hour(s) $minutes minute(s) late"
else
echo "He is logged in $time minute(s) late"
fi
exit 0

else
let time++

# You can use following formats also
# time=`expr $time + 1 `
# time=$((time+1))

sleep 60
fi
done

Output:
[root@localhost shell]# sh isuserloggedin.sh
you have suplied wrong arguments
usage : isuserloggedin.sh username
[root@localhost shell]# sh isuserloggedin.sh root
User root is logged in
He is logged in 0 minute(s) late
[root@localhost shell]# sh isuserloggedin.sh roott
roott is not a valid user
Run script in background
[root@localhost shell]# sh isuserloggedin.sh venu &
[1] 15917
[root@localhost shell]# User venu is logged in
He is logged in 3 minute(s) late

[1]+ Done sh isuserloggedin.sh venu
Run script in background then foreground it
[root@localhost shell]# sh isuserloggedin.sh venu &
[1] 16223
[root@localhost shell]# fg
sh isuserloggedin.sh venu
User venu is logged in
He is logged in 1 minute(s) late
[root@localhost shell]#

Bash Script to Check whether a user has an account in your system

#!/bin/bash
# validuser.sh
# Usage: validuser.sh username
# Script to check whether suplied user has an account in your system

if [ $# -ne 1 ]
then
echo "You supplied wrong arguments"
echo "Usage : `basename $0` user_name"
exit 1
fi

#grep -w "$1" /etc/passwd > /dev/null
grep -w "^$1" /etc/passwd > /dev/null
if [ $? -eq 1 ]
then
echo "$1 is not a valid user"
else
echo "$1 is a valid user"
fi

# Using greps -q option you can simplify and faster your script
# if `grep -qw "^$1" /etc/passwd`
# greps -q option prints nothing just returns exit status 0 or 1

Out Put:
[root@localhost shell]# sh validuser.sh
You supplied wrong arguments
usage : validuser.sh user_name
[root@localhost shell]# sh validuser.sh venu
venu is a valid user
[root@localhost shell]# sh validuser.sh venuk
venuk is not a valid user
[root@localhost shell]# sh validuser.sh root
root is a valid user
[root@localhost shell]# sh validuser.sh roott
roott is not a valid user
[root@localhost shell]#

Wednesday, September 2, 2009

How to prompt user to enter input within the time limit in a shell script

There are various ways to read input within the time limit in shell script. I am posting 4 methods here.First three are direct methods. Final one implemented with some logic, just for practice only.

Method 1:


#!/bin/bash
# timedinput1.sh: prompts times out at five seconds.
# Using read command

timelimit=5
echo -e " You have $timelimit seconds\n Enter your name quickly: \c"
name=""
read -t $timelimit name
#read -t $timelimit name <&1
# for bash versions bellow 3.x
if [ ! -z "$name" ]
then
echo -e "\n Your name is $name"
else
echo -e "\n TIME OUT\n You failed to enter your name"
fi
Output:
[root@localhost shell]# sh timedinput1.sh
You have 5 seconds
Enter your name quickly: king

Your name is king
[root@localhost shell]# sh timedinput1.sh
You have 5 seconds
Enter your name quickly:
TIME OUT
You failed to enter your name

Method 2:


#!/bin/bash
# timedinput2.sh
# Using stty command

timelimit=5
# Time limit to enter input
echo -e " You have only $timelimit seconds\n Enter your name quickly: \c"
name=""
stty -icanon min 0 time ${timelimit}0

# "min N" with -icanon, set N characters minimum for a completed read
# "time N" with -icanon, set read timeout of N tenths of a second (i.e. 50 means 5
seconds )

read name
if [ ! -z "$name" ]
then
echo " Your name is $name"
else
echo -e "\n TIME OUT\n You failed to enter your name"
fi
stty sane
#restore terminal settings
Output:
[root@localhost shell]# sh timedinput2.sh
You have only 5 seconds
Enter your name quickly: Sachin Ramesh Tendulkar
Your name is "Sachin Ramesh Tendulkar"
[root@localhost shell]# sh timedinput2.sh
You have only 5 seconds
Enter your name quickly:
TIME OUT
You failed to enter your name
Observation:
There is difference between method1 and method2.In method1 you should to enter input within 5 seconds.But in method 2 you have 5 seconds after a character has been hit.This is because time n means wait till n seconds after a character has been hit.So in method2 you can give any length of input.

Method3:


#!/bin/bash
# timedinput3.sh
# using TMOUT environment variable

TMOUT=5
# TMOUT is an Internal Variable
# If the $TMOUT environment variable is set to a non zero value time, then the shell prompt will time out after $time seconds.This will cause a logout.
# If you run this script in current shell after 5 seconds you will be logout

echo -e " You only have $TMOUT seconds\n Enter your name quickly: \c"
name=""
read name
if [ ! -z "$name" ]
then
echo " Your name is $name"
else
echo -e "\n TIME OUT\n You failed to enter your name"
fi
Output:
[root@localhost shell]# sh timedinput3.sh
You only have 5 seconds
Enter your name quickly: Ricky ponting
Your name is "Ricky ponting"
[root@localhost shell]# sh timedinput3.sh
You only have 5 seconds
Enter your name quickly:
TIME OUT
You failed to enter your name

Method4:


#!/bin/bash
# timedinput4.sh
# Using sleep command

timelimit=5
#set another value if you require

trap 'echo -e "\n TIMEOUT"; exit 14' 14
# Trapping signal 14

echo -e " You only have $timelimit seconds \n What is your name:\c"

sleep $timelimit && kill -s 14 $$ &

# Waits 5 seconds, then sends sigalarm to script($$ environment variable gives pid of current script).
read name
echo " Your name is \"$name\""
kill $!
#kills back ground job (i.e. sleep command)
exit
Output:
[root@localhost shell]# sh timedinput4.sh
You only have 5 seconds
What is your name:Ganguly
Your name is "Ganguly"
[root@localhost shell]# sh timedinput4.sh
You only have 5 seconds
What is your name:Kapil Dev
Your name is "Kapil Dev"
timedinput4.sh: line 16: 3814 Terminated sleep $timelimit && kill -s 14 $$
[root@localhost shell]# sh timedinput4.sh
You only have 5 seconds
What is your name:
TIMEOUT