Shell Script (Nigam&deepesh221110)
Shell Script (Nigam&deepesh221110)
Shell Script (Nigam&deepesh221110)
not?
This Shell Script is developed using Bourne Shell.
1=0
cnt=1
tag=0
echo "Enter a String?"
read str
1 =`echo $str |wc -c`
1 =`expr $l - 1`
1h=`expr $l / 2`
while [ $cnt -le $lh ]
do
c1=`echo $str|cut -c$cnt`
c2=`echo $str|cut -c$l`
if [ $c1 != $c2 ]
then
cnt=$lh
tag=1
fi
cnt=`expr $cnt + 1`
=`expr $l - 1`
done
if [ $tag -eq 0 ]
then
echo "String is Palindrome"
else
echo “String is not Palindrome”
fi
Code:
str="program"
i=${#str}
final=""
while [ $i -gt 0 ]
do
rev=`echo $str | awk '{printf substr($0, '$i', 1)}'`
final=$final$rev
i=$(($i - 1))
done
to reverse a line
*************************************
Code:
str="this script is to reverse"
i=${#str}
word=""
fin=""
final=""
while [ $i -ge 0 ]
do
temp=`echo $str | awk '{printf substr($0, '$i', 1)}'`
if [ \( "$temp" = " " \) -o $i -eq 0 ]
then
wordlen=${#word}
while [ $wordlen -gt 0 ]
do
revtemp=`echo $word | awk '{printf substr($0, '$wordlen', 1)}'`
fin=$fin$revtemp
wordlen=$(($wordlen -1))
done
final=$final$fin" "
fin=""
word=""
temp=""
else
word=$word$temp
fi
i=$(($i - 1))
done
to reverse a string
Code:
[~/temp]$ cat deepak.sh
#! /bin/sh
# reverse a string
len=${#STR}
REV=""
for (( i=$len ; i>0 ; i-- ))
do
REV=$REV""${STR:$i-1:$i}
STR=${STR%${STR:$i-1:$i}}
done
Code:
[~/temp]$ ./deepak.sh
Reversed string
z y x w v u t s r q p o n m l k j i h g f e d c b a
As for trimming, you can trim the leading and trailing white spaces.
Code:
# remove leading white spaces
REV=${REV## }
# remove trailing white spaces
REV=${REV%% }
num1=0
num2=1
count=2
echo -e "\nFinished....."
Fibonacci number
Now we will run a script which calculates n-th Fibonacci number where n will be provided as
input when prompted.
User input 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Output 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
#!/bin/bash
# Fibonacci number shell script
# It takes input one number and show Fibonacci
number of that serial
# Initializes variables
a=0
b=1
count=2 # Used to control the number of iteration
of the while loop
fibonacci_number=$a
Type the script in the editor and save the file as fib.sh. Run it after assinging execute permission:
#!/bin/bash
# Fibonacci number shell script
# It takes input multiple numbers and show Fibonacci
number of those serial
# It stops taking input when -1 is given
Type the script in editor and save as fib_m.sh. Run after assigning execute permission:
#!/bin/bash
# Fibonacci number shell script
# It takes input one number from a file and shows
Fibonacci number of that serial
# Initialize variables
a=0
b=1
count=2 # Used to control the number of iteration
of the while loop
fibonacci_number=$a
Type the script in editor and save as fib_f.sh. Before running the script create a file containing a
single number. Suppose, we create the file named fib.in. Run the script after assigning execute
permission:
{cs1:~} echo 11 > fib.in
{cs1:~} chmod +x fib_f.sh
{cs1:~} fib_f.sh fib.in
Fibonacci 11 = 89
#!/bin/bash
# Fibonacci number shell script
# It takes input more than one number from a file
each residing in a single line
# and shows Fibonacci number of that serial
# Initialize variables
a=0
b=1
count=2 # Used to control the number of
iteration of the while loop
fibonacci_number=$a
Type the script in editor and save as fib_m_f.sh. Here is a sample input file fib_m.in containing
values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and 20. Right-click the link and save the file in appropriate
location. Run the script after assigning execute permission:
Exercise
In the first Fibonacci script, add error check on the input for negative integers and real numbers
as they are not defined in the series. If user inputs such number the output should be "not
defined". For example:
Showing newest posts with label Shell Scripts. Show older posts
Examples:
Method 1:
#!/bin/bash
# SCRIPT: palindrome1.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this script I uses the well known method, compare first
character
# with last character, up to middle of the string. One mismatch in
the
# scanning leads to immediate termination of the scanning as it is
# not a palindrome. To extract character from string, I will use
cut
# command with the -c option with the position number.
#
###################################################################
##
# Arguments Checking
#
###################################################################
##
if [ $# -eq 0 ]
then
echo -n "Enter a String: "
read orgstr
else
orgstr=$*
fi
###################################################################
##
# Variable Initialization
#
###################################################################
##
# Remove all punctuations from input string and convert upper case
to
# lower or lower case to upper.
Flag=0
for ((i=1;i<=mid;i++))
do
c1=`echo $String|cut -c$i` # extracts from beginning
c2=`echo $String|cut -c$len` # extracts from last
if [ $c1 != $c2 ]
then
Flag=1
let len--
done
if [ $Flag -eq 0 ]
then
echo "\"$orgstr\" is a Palindrome"
else
echo "\"$orgstr\" is not a Palindrome"
fi
OUTPUT:
Method 2:
#!/bin/bash
# SCRIPT: palindrome2.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this script I uses the well known method, compare first
character
# with last character, up to middle of the string. One mismatch in
the
# scanning leads to immediate termination of the scanning as it is
# not a palindrome. To extract a character from the string, I will
use
# string manipulation operations.So you need to know how to
manipulate
# strings to understand this script. I will give little bit of
explan-
# tion at the end of this script.
#
###################################################################
##
# Arguments Checking
#
###################################################################
##
###################################################################
##
# Variable Initialization
#
###################################################################
##
# Remove all punctuations from input string and convert upper case
to
# lower or lower case to upper.
i=0
Flag=0
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
if [ $Flag -eq 0 ]
then
echo "\"$orgstr\" is a Palindrome"
else
echo "\"$orgstr\" is not a Palindrome"
fi
Substring Extraction:
${string:position}
Extracts substring from $string at $position.
${string:position:length}
Extracts $length characters of substring from $string at
$position
For example
[root@localhost www]# tempvar=madam
[root@localhost www]# echo ${tempvar: -1:1}
m
[root@localhost www]# echo ${tempvar:-1:1}
madam
OUTPUT:
Method 3:
#!/bin/bash
# SCRIPT: palindrome3.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# This simply uses the 'rev' utility which is used to reverse lines
of
# a file. Then check if the reverse of the string is same as the
# original.rev command is part of util-linux-ng or util-linux
package.
#
else
echo "Install util-linux or util-linux-ng package"
fi
OUTPUT:
Method 4:
#!/bin/bash
# SCRIPT: palindrome4.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this method we are not using 'rev' command to reverse the
string.
# Using Substring Removal method or Substring Extraction method we
# will reverse the string, then compare it with oldstring.
#
###################################################################
##
# Arguments Checking
#
###################################################################
##
###################################################################
##
# Variable Initialization
#
###################################################################
##
oldstring=$String
newstring=
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
while [ -n "$String" ]
do
temp=${String#?}
letter=${String%"$temp"}
String=$temp
newstring=${letter}${newstring}
done
if [ "$oldstring" = "$newstring" ]
then
echo "\"$orgstr\" is a palindrome"
else
echo "\"$orgstr\" is not a palindrome"
fi
#i=0
#while [ $i -lt ${#String} ]
#do
# letter=${String:$i:1}
# newstring=${letter}${newstring}
# let i++;
#done
#
#if [ "$String" = "$newstring" ]
#then
# echo "\"$orgstr\" is a palindrome"
#else
# echo "\"$orgstr\" is not a palindrome"
#fi
Substring Removal:
${string#substring}
Strips shortest match of $substring from front of $string.
Example:
[root@www]# tempvar=madam
[root@www]# echo ${tempvar#m}
adam
[root@www]# echo ${tempvar#ma}
dam
[root@www]# echo ${tempvar#?}
adam
${string%substring}
Strips shortest match of $substring from back of $string.
Example:
[root@www]# temp=${tempvar#?}
[root@www]# echo $temp
adam
[root@www]# echo ${tempvar%$temp}
m
OUTPUT:
#!/bin/bash#!/bin/bash
# SCRIPT: insertionsort.sh
#
# LOGIC: Here, sorting takes place by inserting a particular
element
# at the appropriate position, that’s why the name insertion
sorting.
# In the First iteration, second element ARRAY[1] is compared with
# the first element ARRAY[0]. In the second iteration third element
# is compared with first and second element. In general, in every
# iteration an element is compared with all the elements before it.
# While comparing if it is found that the element can be inserted
at
# a suitable position, then space is created for it by shifting the
# other elements one position up and inserts the desired element at
# the suitable position. This procedure is repeated for all the
# elements in the list.
#
###################################################################
##
# Define Functions Here
#
###################################################################
##
printnumbers()
{
echo ${ARRAY[*]}
}
sortnumbers()
{
for((i=1;i<count;i++))
do
Temp=${ARRAY[i]}
j=$((i-1))
while [ $Temp -lt ${ARRAY[j]} ]
do
ARRAY[j+1]=${ARRAY[j]}
let j--
if [ $j == -1 ]
then
break
fi
done
ARRAY[j+1]=$Temp
done
}
###################################################################
##
# Variable Initialization
#
###################################################################
##
read -a ARRAY
count=${#ARRAY[@]}
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
echo "-------------------------------------------------------------
--"
printnumbers
sortnumbers
printnumbers
echo "-------------------------------------------------------------
--"
OUTPUT:
#!/bin/bash#!/bin/bash
# SCRIPT: selectionsort.sh
#
# LOGIC : Here, to sort the data in ascending order, the first
element
# ARRAY[0] is compared with all the other elements till the end of
the
# array. If it is greater than any other the elements then they are
# interchanged. So after the first iteration of the outer for loop
# smallest element will be placed at the first position. The same
pro-
# cedure is repeated for the other elements too.
#
###################################################################
##
# Define Functions Here
#
###################################################################
##
printnumbers()
{
echo ${ARRAY[*]}
}
swap()
{
temp=${ARRAY[$1]}
ARRAY[$1]=${ARRAY[$2]}
ARRAY[$2]=$temp
}
sortnumbers()
{
for ((i=0;i<count;i++))
do
min=$i
for ((j=i+1;j<count;j++))
do
if [ ${ARRAY[j]} -lt ${ARRAY[min]} ]
then
min=$j
fi
done
swap $i $min
done
}
###################################################################
##
# Variable Initialization
#
###################################################################
##
read -a ARRAY
count=${#ARRAY[@]}
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
echo "-------------------------------------------------------------
--"
printnumbers
sortnumbers
printnumbers
echo "-------------------------------------------------------------
--"
OUTPUT:
#!/bin/bash
# SCRIPT: bubblesort.sh
# LOGIC:
# Bubble sort is a simple sorting, it works by repeatedly stepping
# through the list to be sorted, comparing two items at a time and
# swapping them if they are in the wrong order. If you are sorting
# the data in Ascending order, at the end of the first pass, the
# "heaviest" element has move to bottom. In the second pass, the
# comparisons are made till the last but one position and now
second
# largest element is placed at the last but one position. And so
# forth.
#
###################################################################
##
# Define Functions Here
#
###################################################################
##
printnumbers()
{
echo ${ARRAY[*]}
#You can also use bellow code
#for ((i=0;i<count;i++))
#do
#echo -n " ${ARRAY[i]} "
#done
}
exchange()
{
temp=${ARRAY[$1]}
ARRAY[$1]=${ARRAY[$2]}
ARRAY[$2]=$temp
sortnumbers()
{
for (( last=count-1;last>0;last--))
do
for((i=0;i<last;i++))
do
j=$((i+1))
if [ ${ARRAY[i]} -gt ${ARRAY[j]} ]
then
exchange $i $j
fi
done
done
}
###################################################################
##
# Variable Initialization
#
###################################################################
##
read -a ARRAY
count=${#ARRAY[@]}
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
echo "-------------------------------------------------------------
-"
printnumbers
echo
sortnumbers
printnumbers
echo "-------------------------------------------------------------
-"
OUTPUT:
#!/bin/bash
# SCRIPT: bubblesort2.sh
# Without using arrays
#
###################################################################
##
# Define Functions Here
#
###################################################################
##
printnumbers()
{
k=1
while [ $k -le $max ]
do
eval echo -n "\$x$k"
echo -n " "
let k++
done
echo
}
###################################################################
##
# Variable Initialization
#
###################################################################
##
###################################################################
##
# Main Script Starts Here
#
###################################################################
##
for (( last=count-1;last>0;last--))
do
for ((i=1;i<last;i++))
do
j=$((i+1))
eval sval=\$x$i
eval nval=\$x$j
#The eval command evaluates the command line to complete any shell
#substitutions necessary and then executes the command. So $i and
$j
#substituted first then $x1 and $x2 evaluated.
OUTPUT:
#!/bin/bash
# SCRIPT: digclock.sh
# USAGE: ./digiclock &
# PURPOSE: Displays time and date in the top right corner of the
# screen using tput command.
# To stop this digclock use command "kill pid"
################################################################
Columns=$(tput cols)
Startpoint=$(($Columns-22))
while :
do
Time=`date +%r`
Date=`date +"%d-%m-%Y"`
tput sc #Save the cursor position&attributes
tput cup 0 $Startpoint
# print time and date in the top right corner of the screen.
sleep 1
done
#!/bin/bash
# SCRIPT: digclock.sh
# USAGE: ./digiclock &
# PURPOSE: Displays time and date in the top right corner of the
# screen using ANSI escape sequences.
# To stop this digclock use command kill pid.
################################################################
Columns=$(tput cols)
Startpoint=$(($Columns-22))
while :
do
Time=`date +%r`
Date=`date +"%d-%m-%Y"`
echo -en "\033[s" #save current screen position & attributes
# print time and date in the top right corner of the screen
echo -e -n "\033[u"
sleep 1
done
Output:
When you run digclock.sh, the terminal will return the job number
and
process identifier (PID) of the digclock.sh process. From above
output
you can find job number is "1" and PID is "15800".
1. Using the kill command and specifying the job number or process
ID.
If you don't remember job number or PID, you can get job number
by
running jobs command and PID by ps command.
$ jobs
[1]+ Running ./digclock.sh &
$ shell]# ps | grep digclock
15800 pts/1 00:00:00 digclock.sh
$ kill %1
$
[1]+ Terminated ./digclock.sh
or
$ kill 15800
$
[1]+ Terminated ./digclock.sh
$ fg 1
./digclock.sh
Ctrl+c
$
With this script, you can display not only a clock, but other
useful
information as well. For example,monitoring free space with df
command
or CPU's load average with uptime command. Samba, Apache, and many
other servers have status commands where you can extract pieces of
information to show this way.
Posted by venu k at 6:05 AM 0 comments
#!/bin/bash
# SCRIPT : upload.sh
# USAGE : ./upload.sh [-d remote directory path] -f "File-to-
upload"
# -d option is optional by default it takes servers home
dir
# or
# ./upload.sh "Filename-to-upload"
#
# PURPOSE : Upload file to remote ftp server.
Usage()
{
echo " USAGE
"
echo " $0 [-d \"Remote Directory Path\"] -f \"Filename-to-
upload\""
echo "-------------------------- or -----------------------------
"
echo " $0 Filename-to-upload"
exit 1
}
# Remove comment lines within the here document before run the
script
binary
cd $Dname
put "$Fname"
bye
ServerEnd
exit 0
OUTPUT:
#!/bin/bash
#
# SCRIPT: ddcopy.sh
# PURPOSE: Copies files and shows the progress of copying.
#
#............................USAGE...........................
# This script copies only files not directories
# ddcopy <Source filename or Path> <Destination filename or Path>
# ddcopy <Source filename or Path> <Destination Directory or Path>
##################################################################
# Arguments Checking #
##################################################################
if [ $# -eq 2 ]
then
Source="$1"
Dest="$2"
if [ ! -e "$1" ] # Check source file exist or not
then
echo "$0: cannot stat '$1': No such file or directory"
exit 1
elif [ -d "$1" ]
then
echo "$0: Source file '$1' is a directory"
exit 1
fi
egrep -q "^\/|\/$" <<<$2
if [ $? -eq 0 -a ! -d $2 ]
then
echo "$0: cannot create regular file '$2' : Is a directory"
exit 1
fi
if [ -d "$2" ]
then
filename=`basename "$1"`
$(egrep -q "\/$" <<<$2) && Dest="$2$filename" ||
Dest="$2/$filename"
fi
if [ -e "$Dest" -a -f "$Dest" ]
then
echo -n "$0: $Dest already exist : overwrite '$Dest' (y/n)?
"
read answer
if [ "$answer" = "n" -o "$answer" = "N" ]
then
exit 1
fi
fi
fi
###################################################################
# DEFINE VARIABLES HERE #
###################################################################
if [ $lastblock -gt 0 ]
then
let blocks++
fi
addblocks=$((blocks%20))
if [ $addblocks -gt 0 ]
then
adjustblocks=$((20-addblocks))
blocks=$((blocks+adjustblocks))
fi
Count=$((blocks/20))
###################################################################
# MAIN PROGRAM STARTS HERE #
###################################################################
for ((i=1;i<=20;i++))
do
Skip=$((Skip+$Count))
Seek=$((Seek+$Count))
j=$((j+3)) # 60/20 each part is 3 chars
length
done
printf "\e[0m\n"
#echo -e "\033[0m"
OUTPUT:
Screen Shot1:
Screen Shot2:
Screen Shot3:
#!/bin/bash
# SCRIPT: primenumbers.sh
# USAGE : ./primenumbers.sh <Range Value>
# or;
# ./ primenumbers.sh <Start Range Value> <End Range Value>
# PURPOSE: Produce prime numbers within a range lmit.
Usage()
{
echo "********BAD ARGUMENTS**********"
echo "Usage: scriptname <Range Value >"
echo " or "
echo "Usage: scriptname <Start Range Value> <End Range Value>"
exit 1
}
################# ARGUMENTS CHECKING #################
count=1
[ "$Prime" = "yes" ] && printf "%5d " $num && let count++
OUTPUT:
$ ./primenumbers.sh 1 350
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
$ ./primenumbers.sh 200
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199
NOTE:
this script can't find the highest prime number,but it can figure out the highest prime number your
system is capable of calculating.
NOTE:
Method 1 is a very bad method it takes more and more time for
calculation.
Method 3 and Method 4 have given good results, they have taken less
time.
As per my observation Method 3 is quite a bit faster than the
Method 4.
Method 1:
#!/bin/bash
# SCRIPT: prime1.sh
# USAGE : ./prime1.sh
# PURPOSE: Finds whether given number is prime or not
################################################################
Method 2:
#!/bin/bash
# SCRIPT: prime2.sh
# USAGE : ./prime2.sh
# PURPOSE: Finds whether a given number is prime or not
[ $num -lt 2 ] && echo "Sorry 0 and 1 are not prime numbers" &&
exit 1
i=2
Method 3:
#!/bin/bash
# SCRIPT: prime3.sh
# USAGE : ./prime3.sh
# PURPOSE: Finds whether a given number is prime or not.
if [ $# -ne 1 ]
then
echo "Usage: scriptname "
exit 1
fi
expr $1 + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "Sorry, You supplied non numerical value"
exit 2
fi
[ $1 -lt 2 ] && echo "Sorry,Values < 2 are not prime numbers" &&
exit 1
num=$1
i=2
Method 4:
#!/bin/bash
# SCRIPT: prime4.sh
# USAGE : ./prime4.sh
# PURPOSE: Finds whether a given number is prime or not.
if [ $# -ne 1 ]
then
echo "Usage: scriptname "
exit 1
fi
expr $1 + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "Sorry, You supplied non numerical value"
exit 2
fi
[ $1 -lt 2 ] && echo "Sorry,Values < 2 are not prime numbers" &&
exit 1
num=$1
i=2
done
echo "$num is a prime number"
OUTPUT1:
real 3m35.435s
user 0m41.738s
sys 1m53.501s
real 2m40.494s
user 0m28.650s
sys 1m19.991s
real 0m3.040s
user 0m2.778s
sys 0m0.232s
real 0m3.150s
user 0m2.898s
sys 0m0.211s
OUTPUT2:
real 0m0.077s
user 0m0.014s
sys 0m0.048s
real 0m0.008s
user 0m0.004s
sys 0m0.006s
real 0m0.008s
user 0m0.005s
sys 0m0.002s
#!/bin/bash
#
# SCRIPT: ddcopy_progress.sh
# PURPOSE: This script is used to watch progress of copying.
#
# Note: I am using destination file as $$.temp .This is because,
# after testing you can easily delete temp files using
# rm -f *.temp
#############################################
# Arguments Checking #
#############################################
#############################################
# DEFINE VARIABLES HERE #
#############################################
if [ $lastblock -gt 0 ]
then
let blocks++
fi
addblocks=$((blocks%20))
if [ $addblocks -gt 0 ]
then
adjustblocks=$((20-addblocks))
blocks=$((blocks+adjustblocks))
fi
Count=$((blocks/20))
###############################################
# MAIN PROGRAM STARTS HERE #
###############################################
for ((i=1;i<=20;i++))
do
done
printf "\e[0m\n"
#echo -e "\033[0m"
Output:
Screen Shot1:
Screen Shot2:
Screen Shot3:
Screen Shot4:
Observation:
I tested above script with different block count.But I didn't get accurate result.
Some times less count script given good result, some times more block count given
good result.
I copied 1.8 GB Movie file with this script.With time command it has give bellow
result.
real 1m12.646s
user 0m0.043s
sys 0m7.854s
From my observation this script has taken less time compared with mouse copy and
paste method. Copy and paste has taken 1m14.02s averagely.
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
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:
#!/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
}
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
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:
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
#!/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
if [ $# -ne 1 ]
then
echo "You supplied wrong arguments"
echo "Usage : `basename $0` user_name"
exit 1
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]#
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
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
echo -e " You only have $timelimit seconds \n What is your name:\c"
# 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
# Argument check
# Minimum 2 arguments you should to supply
ARGS=2
BADARGS=65
if [ $# -lt "$ARGS" ]
then
echo
echo "Invalid Arguments"
echo "Usage: $0 first-number second-number"
echo
exit $BADARGS
fi
# Preserve command line argument for future use
cmdargs=$*
function Euclidean()
{
if [ $2 -eq 0 ]
then
return $1
else
Euclidean $2 $(($1%$2)) # calling function recursively
fi
}
Euclidean $1 $2
return=$?
# $? returns the exit status of script. This is one method to capture return value of a function
shift
# Shifts command line arguments one step.Now $1 holds second argument
while true
do
shift
# shift is used to pick up next command line argument to continue iteration
# $# holds total number of arguments.At every shift operation its value decreases one
if [ $# -eq 0 ]
then
break 2
fi
Euclidean $return $1
return=$?
done
echo "GCD of $cmdargs is $return"
exit 0
Method 1:
#!/bin/bash
#************************************************************************************
*******
# gcd.sh: greatest common divisor uses Eclidean algorithm
# Usage : gcd.sh number1 number2
# The algorithm used to calculate the GCD between two integers is known as the Euclidean
# algorithm(Recursive method).
#************************************************************************************
*******
#----------------------------------------------------------------------
# Argument check
ARGS=2
BADARGS=65
if [ $# -ne "$ARGS" ]
then
echo ; echo "Invalid Arguments"
echo "Usage: $0 first-number second-number" ; echo
exit $BADARGS
fi
isnumber()
{
if [ $1 -eq $1 2> /dev/null ]
then
:
# : is a null command.This is the shell equivalent of a "NOP"(do nothing)
else
echo -e "\nYou supplied one bad argument \"$1\" is not a number"
echo -e "Usage: $0 first-number second-number\n"
exit $BADARGS
fi
}
isnumber $1
isnumber $2
# ---------------------------------------------------------------------
function Euclidean()
{
if [ $2 -eq 0 ]
then
return $1
else
Euclidean $2 $(($1%$2))
# calling function recursively
fi
}
Euclidean $1 $2
# $? returns the exit status of script. This is one method to capture return value of a function
exit 0
Method 2:
#!/bin/bash
# gcd2.sh
# Usage: gcd2.sh number1 number2
# For argument check see method 1
gcd ()
{
dividend=$1
divisor=$2
# Arbitrary assignment.
#! It doesn't matter which of the two is larger.
remainder=1
if [ $divisor -eq 0 ]
then
echo "GCD of $dividend and $divisor = $dividend"
exit 0
fi
dividend=$divisor .
divisor=$remainder
done
}
# Last $dividend is the gcd.
gcd $1 $2
Method 3:
#!/bin/bash
# gcd3.sh
# Usage: gcd3.sh
# This script doesn't use command line arguments.You should to enter two numbers when asking
clear
trap "" 1 2 3 20
lines=`tput lines`
b=`expr $lines / 2 - 4 `
## center function
center()
{
columns=`tput cols`
until [ -z "$1" ]
do
for ((i=1;i<$(((columns-${#1})/2));i++)) do echo -n " " done echo -e "\033[1m \033[5m \033[42m $1
\033[0m " shift done } ## End of center function while true do clear tput cup $b 0
center " TERMINAL LOCKED "
center "Press any key to unlock"
read key
echo -n "enter password : "
read -s password
while true
do
if [ $password = "open2world" ]
then
clear
break 2
# breaks second outer loop
else
echo -e "\n You are an illegal user "
echo -e "\n Enter any key"
read
break
fi
done
done
Analysis :
The trap command allows you to execute a command when a signal is received by your script. It works
like this:
"signals" is a list of signals to interrupt and "arg" is a command to execute when one of the signals is
received. If "arg" is not supplied script doesn't do any thing after receiving signal.
A signal is a message which can be sent to a running process. Some times called
software interrupts.
Note: There are different standards(POSIX,SUSv) to determine signals and its values.
I tested Above signals in Fedora 9, Other systems may support them or not depending on system
standard(I think almost all standards supports above signals and values).
More stuff:
I used "tput cols" and "tput lines" commands to collect number of columns and lines.
You can also directly use bash variables $LINES ,$COLUMNS to get columns and lines.But
you should to run your script in current shell only. If you run your script in sub shell
current shell will not export $LINES and $COLUMNS variable values.
BACKUPFILE=backup-`date +"%m-%d-%Y"`
# Embeds date in backup filename
archive=${1:-$BACKUPFILE}
#If no filename specified default to backup-MM-DD-YYYY
depth()
{
#Do a small depth checking how deep into the tree we are
k=0
while [ $k -lt $1 ]
do
echo -n " "
let k++
#or use k=`expr $k + 1`
done
}
traverse()
{
# Traverse a directory
ls "$1"while read i
do
depth $2
if [ -d "$1/$i" ]
then
echo Directory: $1/$i
# $1 is directory path
if [ -z "$1" ]
then
# Here we are giving '0' is the current depth of direcory
traverse . 0
else
traverse $1 0
fi
▼ 2010 (12)
o ▼ July (4)
Shell Script to Check Whether a String is Palindro...
Insertion Sort Shell Script
Selection Sort Shell Script
Bubble Sort Shell Script
o ► May (1)
How to Read a File Line by Line in a Shell Script
o ► April (2)
Shell Script to Display Time and Date in the Top ...
How to Handle Cursor Movement in a Shell Script
o ► March (3)
Creating a User Group and Shared Directory
UNIX/Linux Advanced File Permissions - SUID,SGID a...
Linux File and Directory Permissions
o ► February (1)
Shell Script to Upload a File to the Remote FTP Se...
o ► January (1)
Shell Colors: colorizing shell scripts
► 2009 (24)
o ► December (1)
Copy Progress Bar Shell Script V2
o ► November (7)
Linux Baby Rocker
Shell Script To Produce Prime Numbers Within A Ran...
Shell Script to Find Prime Number
How to Pass Arguments to Shell Script
Shell Script to Check Whether Given Year is a Leap...
Copy Progress Bar Shell Script
Shell Script to Create a File with Specified Numbe...
o ► October (7)
Shell Script to Find Factorial of a Number
For Loop Example-2
How to Execute a Shell Script
Bash for loop example-1
Bash for Loop Syntax
Shell Script To Print Pyramid - Using while Loop
Shell Script To Print Pyramid-Using for Loop
o ► September (5)
Sample System Monitor Shell Script - Using Options...
Sample System Monitor Shell Script -Menu Based
Bash Script to check after every one minute whethe...
Bash Script to Check whether a user has an account...
How to prompt user to enter input within the time ...
o ► August (4)
What is the difference between Hard Link and Soft ...
GCD of more than two numbers
GCD of two nubers
Terminal Lock Program
► 2008 (9)
o ► June (4)
Bash variables scope
Bash variables type
Backup files to tarred and zip file
Traversing directory using depth first search
o ► April (4)
MENU DRIVEN PROGRAM USING DIALOG UTILITY
Displaying chess board on the screen
How can get nth line from a file
When not to use shell scripts
o ► March (1)
Why shell(bash) programming
Labels
Article (13)
Beginners Scripts (8)
Linux Fun (1)
Shell Scripts (22)
Counter
Followers
Popular Posts
Shell Colors: colorizing shell scripts
NOTE:
Method 1 is a very bad method it takes more and more time for
calculation.
Method 3 and Method 4 have given good results, they have taken less
time.
As per my observation Method 3 is quite a bit faster than the
Method 4.
Method 1:
#!/bin/bash
# SCRIPT: prime1.sh
# USAGE : ./prime1.sh
# PURPOSE: Finds whether given number is prime or not
################################################################
Method 2:
#!/bin/bash
# SCRIPT: prime2.sh
# USAGE : ./prime2.sh
# PURPOSE: Finds whether a given number is prime or not
[ $num -lt 2 ] && echo "Sorry 0 and 1 are not prime numbers" &&
exit 1
i=2
Method 3:
#!/bin/bash
# SCRIPT: prime3.sh
# USAGE : ./prime3.sh
# PURPOSE: Finds whether a given number is prime or not.
################ ARGUMENTS CHECKING #################
if [ $# -ne 1 ]
then
echo "Usage: scriptname "
exit 1
fi
expr $1 + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "Sorry, You supplied non numerical value"
exit 2
fi
[ $1 -lt 2 ] && echo "Sorry,Values < 2 are not prime numbers" &&
exit 1
num=$1
i=2
done
Method 4:
#!/bin/bash
# SCRIPT: prime4.sh
# USAGE : ./prime4.sh
# PURPOSE: Finds whether a given number is prime or not.
################ ARGUMENTS CHECKING #################
if [ $# -ne 1 ]
then
echo "Usage: scriptname "
exit 1
fi
expr $1 + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "Sorry, You supplied non numerical value"
exit 2
fi
[ $1 -lt 2 ] && echo "Sorry,Values < 2 are not prime numbers" &&
exit 1
num=$1
i=2
done
echo "$num is a prime number"
OUTPUT1:
real 2m40.494s
user 0m28.650s
sys 1m19.991s
real 0m3.040s
user 0m2.778s
sys 0m0.232s
real 0m3.150s
user 0m2.898s
sys 0m0.211s
OUTPUT2:
real 0m0.059s
user 0m0.011s
sys 0m0.038s
real 0m0.008s
user 0m0.004s
sys 0m0.006s
real 0m0.008s
user 0m0.005s
sys 0m0.002s
Method 1:
#!/bin/bash
#
# SCRIPT : leapyear.sh
# PURPOSE: Checks whether given year is a leap year or not
# USAGE : sh leapyear.sh
# If Year value not supplied, it takes current year as default
#
# This script based on, One year has the length of 365 days, 5 hours,
# 48 minutes and 47 seconds. Because this is rather non-functional,
# a normal year has been given 365 days and a leap year 366 days.
#####################################################
############### DEFINE FUNCTIONS HERE ####################
#####################################################
Leap()
{
# This function tells you if the argument is a leap year or not...
YEAR=$1
NO_OF_DAYS=$(cal $YEAR |egrep "^[ 0-9][0-9]| [ 0-9][0-9]$" |wc -w)
# cal command pipes total months and dates to egrep, egrep remove all
lines
# not starting with number or ending with number, then pipes remaining
lines
# to wc command. wc command counts total number of words(days).
#####################################################
############### MAIN PROGRAM STARTS HERE #################
#####################################################
Year=${1:-$(date +%Y)}
if [ $Year -lt 1 -o $Year -gt 9999 ]
then
echo "Illegal Year Value: Use 1-9999"
exit 1
fi
Leap $Year
Method 2:
#!/bin/bash
#
# SCRIPT : leapyear.sh
# PURPOSE: Checks whether given year is a leap year or not
# USAGE : sh leapyear.sh
# If Year value not supplied, it takes current year as default
#
# This script based on,A leap year comes every 4 years,
# but not every 100 years, then again every 400 years.
#####################################################
############### ARGUMENTS CHECKING #####################
#####################################################
YEAR=${1:-`date +%Y`}
#####################################################
############### DECLARE VARIABLES HERE ###################
#####################################################
rem1=$((YEAR%4))
rem2=$((YEAR%100))
rem3=$((YEAR%400))
#####################################################
############## MAIN PROGRAM STARTS HERE ##################
#####################################################
if [ ${rem3} = "0" ]
then
echo "$YEAR Is A Leap Year"
exit
fi
OUTPUT:
#!/bin/bash
#
# SCRIPT: bigfile.sh
# PURPOSE: This script is used to create a text file that
# has a specified number of lines that is specified
# on the command line.
#
usage()
{
echo "............USAGE ERROR............"
echo "USAGE: $0 <number_of_lines_to_create>"
}
# Argument Checking
# Beginning of Main
while ((LINE_COUNT < TOTAL_LINES))
do
CHAR_COUNT=0 # Initialize the CHAR_COUNT to zero on every new line
let LINE_COUNT++
echo>>$OUT_FILE # Give a newline character
done
Posted by venu k at 11:56 AM 0 comments
Method 1:
#!/bin/bash
# fact1
# Finding factorial of a given number
#
done
echo "factorial of $n is $fact"
Method 2:
#!/bin/bash
# fact2
# Usage : sh fact2 Number
factorial ()
{
local number=$1
if [ $number -eq 0 ]
then
Factorial=1
else
let "next = number - 1"
factorial $next
Factorial=`echo $number \* $Factorial | bc`
# let "Factorial = $number * $Factorial"
fi
return $Factorial 2>/dev/null
}
Output:
[root@localhost shell]# ./fact1
Enter a number
8
factorial of 8 is 40320
[root@localhost shell]# ./fact1
Enter a number
23
factorial of 23 is 25852016738884976640000
#!/bin/bash
# Usage: forloop2.sh or forloop2.sh number
# Example using for loop
# Prints following format
# *
# * *
# * * *
# * *
# *
n=$(($n-1))
a=1
b=$a
for (( i=$n ; i>=1 ;i-- ))
do
echo -e -n "\033[47m"
a=$(($b+1))
b=$a
k=1
for (( j=1 ; j<=$t ; j++ ))
do
if [ $j -eq $a ]
then
echo -e "\033[43m * \033[47m\c"
if [ $k -lt $i ]
then
a=$((a+2))
let k++
fi
else
echo -n " "
fi
done
echo ""
done
echo -e "\033[0m"
Output:
Method1
c=1
n=$1
echo -e "\033[47m\c" #colourizing output
for ((row=1;row<=n;row++))
do
for ((i=row;i<n;i++))
do
echo -n ' '
done
for ((k=1;k<=c;k++))
do
if [ $((k%2)) -eq 0 ]
then
echo -n " "
else
echo -e "\033[43m * \033[47m\c"
fi
done
for ((i=row;i<n;i++))
do
echo -n ' '
done
c=$((c+2))
echo
done
echo -e "\033[0m" #Restoring colours
unset c i k n row
Method2
#!/bin/bash
n=$1
t=$((2*n - 1 ))
a=$n
b=$((a+1))
echo -e -n "\033[47m"
for (( i=1 ; i<=$n ;i++ ))
do
a=$(($b-1))
b=$a
k=1
for (( j=1 ; j<=$t ; j++ ))
do
if [ $j -eq $a ]
then
a=$((a+2))
let k++
fi
else
echo -n " "
fi
done
echo
done
echo -e "\033[0m"
Output:
#!/bin/bash
# Usage: scriptname argument
# Here argument is height of pyramid
# Output would be pyramid pattern of stars
# 0 *
# 1 ***
# 2 *****
# 3 *******
# 4 *********
# 5 ***********
# 6 *************
# . ***************
# . *****************
# . *******************
# n-1 *********************
# ---\/--- | ---\/---
# n-1 n-1
#
clear
n=$1
row=1;
echo -e "\033[47m"
while [[ $row -le $n ]]
do
loop=1;
spaces=$((n-row))
stars=$((2*row - 1))
There are many ways to handle any task on a Unix platform, but
some
techniques that are used to process a file waste a lot of CPU time.
Most of the wasted time is spent in unnecessary variable assignment
and
continuously opening and closing the same file over and over. Using
a
pipe also has a negative impact on the timing.
I don't explain in depth every thing, but if you know basic shell
scripting, I hope you can understand easily.
#!/bin/bash
# SCRIPT: method1.sh
# PURPOSE: Process a file line by line with PIPED while-read loop.
FILENAME=$1
count=0
cat $FILENAME | while read LINE
do
let count++
echo "$count $LINE"
done
With catting a file and piping the file output to a while read
loop a
single line of text is read into a variable named LINE on each loop
iteration. This continuous loop will run until all of the lines in
the
file have been processed one at a time.
Output:
#!/bin/bash
#SCRIPT: method2.sh
#PURPOSE: Process a file line by line with redirected while-read
loop.
FILENAME=$1
count=0
We still use the while read LINE syntax, but this time we feed the
loop from the bottom (using file redirection) instead of using a
pipe.
You will find that this is one of the fastest ways to process each
line of a file. The first time you see this it looks a little
unusual,
but it works very well.
Unlike method 1, with method 2 you will get total number of lines
out
side of the loop.
Output:
There are always three default "files" open, stdin (the keyboard),
stdout (the screen), and stderr (error messages output to the
screen).
These, and any other open files, can be redirected. Redirection
simply
means capturing output from a file, command, program, script, or
even
code block within a script and sending it as input to another
file,
command, program, or script.
There are two steps in the method we are going to use. The first
step
is to close file descriptor 0 by redirecting everything to our new
file
descriptor 3. We use the following syntax for this step:
exec 3<&0
Now all of the keyboard and mouse input is going to our new file
des-
criptor 3. The second step is to send our input file, specified by
the
variable $FILENAME, into file descriptor 0 (zero), which is
standard
input. This second step is done using the following syntax:
exec 0<$FILENAME
At this point any command requiring input will receive the input
from
the $FILENAME file. Now is a good time for an example.
#!/bin/bash
#SCRIPT: method3.sh
#PURPOSE: Process a file line by line with while read LINE Using
#File Descriptors
FILENAME=$1
count0=
exec 3<&0
exec 0< $FILENAME
exec 0<&3
echo -e "\nTotal $count Lines read"
exec 0<&3
Output:
Its name comes from the surnames of its authors: Alfred Aho, Peter
Weinberger, and Brian Kernighan.
You should see the contents of your /etc/passwd file appear before
your eyes.Now, for an explanation of what awk did. When we called
awk,
we specified /etc/passwd as our input file. When we executed awk,
it
evaluated the print command for each line in /etc/passwd, in
order.All
output is sent to stdout, and we get a result identical to catting
/etc/passwd. Now, for an explanation of the { print } code block.
In
awk, curly braces are used to group blocks of code together,
similar
to C. Inside our block of code,we have a single print command. In
awk,
when a print command appears by itself, the full contents of the
curr-
ent line are printed.
Here is another awk example that does exactly the same thing:
FILENAME=$1
Output:
Awk is really good at handling text that has been broken into
multiple
logical fields, and allows you to effortlessly reference each
individ-
ual field from inside your awk script. The following script will
print
out a list of all user accounts on your system:
#!/bin/bash
#SCRIPT: method5.sh
#PURPOSE: Process a file line by line with head and tail commands
FILENAME=$1
Lines=`wc -l < $FILENAME`
count=0
On each iteration head command extracts top $count lines, then tail
command extracts bottom line from that lines. A very stupid method,
but some people still using it.
Output:
Now take a long breath, we are going test each technique. Before
you
get into test each method of parsing a file line by line create a
large
file that has the exact number of lines that you want to process.
Use bigfile.sh script to create a large file.
$ sh bigfile.sh 900000
real 6m2.911s
user 2m58.207s
sys 2m58.811s
[root@www blog]# time ./method2.sh bigfile.4227 > /dev/null
real 2m48.394s
user 2m39.714s
sys 0m8.089s
[root@www blog]# time ./method3.sh bigfile.4227 > /dev/null
real 2m48.218s
user 2m39.322s
sys 0m8.161s
[root@www blog]# time ./method4.sh bigfile.4227 > /dev/null
real 0m2.054s
user 0m1.924s
sys 0m0.120s
[root@www blog]# time ./method5.sh bigfile.4227 > /dev/null
I waited more than half day, still i didn't get result, then I
created
a 10000-line file to test this method.
[root@www tempdir]# time ./method5.sh file.10000 > /dev/null
real 2m25.739s
user 0m21.857s
sys 1m12.705s
Method 4 came in first place,it has taken very less time 2.05
seconds,
but we can't compare Method 4 with other methods, because awk is
not
just a command, but a programming language too.
Method 2 and method 3 are tied for second place, they produce
mostly
the same real execution time at 2 minutes and 48 seconds . Method 1
came in third at 6 minutes and 2.9 seconds.
Labels: Article
ANSI escape sequences or tput allow you to move the cursor around
the
screen at will. This is more useful for full screen user interfaces
generated by shell scripts, but can also be used in prompts.
The latter two codes are NOT honored by many terminal emulators.
The
only ones that I'm aware of that do are xterm and nxterm - even
though
the majority of terminal emulators are based on xterm code. As far
as
I can tell, rxvt, kvt, xiterm, and Eterm do not support them. They
are
supported on the console.
Example:
BASH BASH
tput cup Y X
Move cursor to screen location X,Y (top left is 0,0)
tput sc
Save the cursor position
tput rc
Restore the cursor position
tput lines
Output the number of lines of the terminal
tput cols
Output the number of columns of the terminal
tput cub N
Move N characters left
tput cuf N
Move N characters right
tput cuu N
up N lines
tput cud N
down N lines
tput bold
Set bold mode
tput dim
turn on half-bright mode
tput smul
begin underline mode
tput rmul
exit underline mode
tput rev
Turn on reverse mode
tput smso
Enter standout mode (bold on rxvt)
tput rmso
Exit standout mode
tput sgr0
Turn off all attributes (doesn't work quite as expected).
tput ech N
Erase N characters
tput clear
clear screen and home cursor
tput el1
Clear to beginning of line
tput el
clear to end of line
tput ed
clear to end of screen
tput ich N
insert N characters (moves rest of line forward!)
tput il N
insert N lines
This is by no means a complete list of what terminfo and tput
allow,
in fact it's only the beginning. man tput and man terminfo if you
want
to know more.
Example:
Hello World
$ tput sc;tput cud 7;tput setaf 4;echo BASH BASH; tput rc;\
> tput sgr0
$ echo -en "\033[s\033[7B\033[0;34m BASH BASH\033[u\033[0m"
Labels: Article
After you have worked for a while with Linux you discover
probably
that there is much more to file permissions than just the "rwx"
bits.
When you look around in your file system you will see "s" and "t"
$ ls -ld /tmp
drwxrwxrwt 29 root root 36864 Mar 21 19:49 /tmp
$ which passwd
/usr/bin/passwd
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 22984 Jan 6 2007 /usr/bin/passwd
What is this "s" and "t" bit? The vector of permission bits is
really
4 * 3 bits long. Yes there are 12 permission bits,not just 9.The
first
three bits are special and are frequently zero. And you almost
always
learn about the trailing 9 bits first.Some people stop there and
never
learn those first three bits.
Here we will discuss about the 3 special attributes other than the
common read/write/execute:
1.Set-User-Id (SUID)
2.Set-Group-Id (SGID)
3.Sticky Bit
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 22984 Jan 6 2007 /usr/bin/passwd
Every process really has two user IDs: the effective user ID and
the
real user ID. (Of course, there's also an effective group ID and
real
group ID.Just about everything that's true about user IDs is also
true
about group IDs) Most of the time,the kernel checks only the
effective
user ID. For example, if a process tries to open a file, the kernel
checks the effective user ID when deciding whether to let the
process
access the file.
Save the following script under the name reids.pl and make it
executable (chmod 755 reids.pl).
#!/usr/bin/perl
# print real UID
print "Real UID: $<\n";
# print real GID
print "Real GID: $(\n";
# print effective UID
print "Effective UID: $>\n";
# print effective GID
print "Effective GID: $)\n";
check file permissions:
$ ls -l reids.pl
-rwxr-xr-x 1 venu venu 203 Mar 24 10:40 reids.pl
Note: For security reasons the s-bit works only when used on
binaries
(compiled code) and not on scripts (an exception are perl scripts).
Scripts,i.e. programs that cannot be executed by the kernel
directory
but need an interpreter such as the Bourne shell or Java,can have
their setuid bit set, but it doesn't have any effect. There are
some
platforms that honor the s bits even on scripts ( some System V
vari-
ants, for example), but most systems don't because it has proven
such
a security headache - most interpreters simply aren't written with
much security in mind. Set the SUID bit on shell script is useless,
that's why I am using perl script here.
When you run the script you will see that the process that runs it
gets your user-ID and your group-ID:
$ ./reids.pl
Real UID: 500
Real GID: 500 500
Effective UID: 500
Effective GID: 500 500
What you observed, the output of the program depends only on the
user
that runs it and not the one who owns the file.
The SUID for any file can be set (mostly by the superuser) with a
special syntax of the chmod command. This syntax uses the character
s
as the permission. Now add SUID permission to the script reids.pl :
Now return from the super user mode to the usual non privileged
mode.
$ ls -l reids.pl
-rwsr-xr-x 1 king venu 203 Mar 24 10:40 reids.pl
The file reids.pl is owned by king and has the s-bit set where
norma-
lly the x is for the owner of the file. This causes the file to be
executed under the user-ID of the user that owns the file rather
than
the user that executes the file. If venu runs the program then this
looks as follows:
$ perl reids.pl
Real UID: 500
Real GID: 500 500
Effective UID: 503
Effective GID: 500 500
The extra octal bit (4) signifies the SUID mode, but find treats
the
"–" before 4000 as representing any other permissions.
Set-Group_Id (SGID):
$ id
uid=503(king) gid=503(king) groups=501(development),503(king)
$ ls -l reids.pl
-rwxr-xr-x 1 king development 203 Mar 25 19:00 reids.pl
$ id
uid=501(venu) gid=504(venu) groups=501(development),504(venu)
$ perl reids.pl
Real UID: 501
Real GID: 504 504 501
Effective UID: 501
Effective GID: 504 504 501
$ perl reids.pl
Real UID: 501
Real GID: 504 504 501
Effective UID: 501
Effective GID: 501 504 501
Real GID and Effective GID are different,here Effective GID is the
king's - the owner of the program.
# ls -ld /home/project/
drwxrwxr-x 16 root development 4096 Mar 26 00:22 /home/project/
$ whoami
king
$ pwd
/home/project/
$ touch temp; ls -l temp
-rw-r--r-- 1 king king 0 Mar 26 12:34 temp
You can see from the ls output that the group owner for project is
development, and that the SGID bit has not been set on the
directory
yet. When king creates a file in project, the group for the file is
king (king's primary gid).
From the ls output above, you know the SGID bit is set because of
the
s in the third position of the group permission set,which replaces
the
x in the group permissions.
$ whoami
king
$ touch temp2; ls -l temp2
-rw-r--r-- 1 king development 0 Mar 26 13:49 temp2
Sticky bit:
The sticky bit(also called the saved text bit) is the last
permission
bit remaining to be discussed. It applies to both regular files and
directories. When applied to a regular file, it ensures that the
text
image of a program with the bit set is permanently kept in the swap
area so that it can be reloaded quickly when the program's turn to
use
the CPU arrives. Previously, it made sense to have this bit set for
programs like vi and emacs. Today,machines with ultra-fast disk
drives
and lots of cheap memory don't need this bit for ordinary files and
that is also useless.
However, the sticky bit become a useful security feature when used
with a directory. The UNIX/Linux system allows users to create
files
in /tmp, but none can delete files not owned by him. That's
possible
because sticky bit set for /tmp directory.
Example:
$ whoami
king
$ pwd
/home/project/
$ touch temp; ls -l
-rw-r--r-- 1 king king 0 Mar 27 13:44 temp
$ whoami
venu
$ rm temp
rm: remove write-protected regular empty file `temp'? Y
$ ls temp
ls: temp: No such file or directory
# chmod +t /home/project
# ls -ld /home/project/
drwxrwxr-t 15 root development 4096 Mar 27 13:46 /home/project/
From the ls output above, you know the sticky bit is set because
of
the t in the third position of the other permission set,which
replaces
the x in the other permissions.
Now repeat same steps again,then you get the following message:
$ whoami
venu
$ ls -l temp
-rw-r--r-- 1 king king 0 Mar 27 17:36 temp
$ rm temp
rm: remove write-protected regular empty file `temp'? y
rm: cannot remove `temp': Operation not permitted
Labels: Article
1 2 3 4 5 6 7 8 9 10
File User Permissions Group Permissions Other Permissions
Type Read Write Execute Read Write Execute Read Write Execute
d r w e r w e r w e
- regular file
d directory
l symbolic link
s socket
p named pipe
$ ls -l sample
-rwxr-xr-- 1 king development 0 Mar 15 00:26 sample
As you can see in this example, the "ls -l" command gives a lot of
information about the file "sample":
- No permissions
The second group (r-x) has a hyphen in the middle slot, which
indica-
tes the absence of write permission by the group owner of the file.
This group owner is development, and all users belonging to the
devel-
opment group have read and execute permissions only.
The third group (r--) has the write and execute bits absent. This
set
of permissions is applicable to others i.e., those who are neither
the
owner king nor belong to the development group. So this file is not
world writable.
If you are owner of the file you can set different permissions
for
the three categories of users --owner,group, and others.It's
important
that you understand them because a little learning here can be a
dangerous thing.A faulty file permission is a sure recipe for
disaster.
Relative Permissions:
a All(ugo)
chmod command also accept more than one file name in the command
line.
When you need to assign the same set of permissions to a group
files,
all the file names have to be specified with a single chmod
command:
More than one permission can also be set; u+rwx is a valid chmod
expression.So setting write and execute permissions for others is
no
problem:
Absolute Permissions:
I. Read permission - 4
II. Write permission - 2
III. Execute permission - 1
We see that "1" stands for execute only, "2" stands for write
only,
"4" stands for read only.To combine the permissions you can simply
add
1, 2 and 4 to get a needed combination. For instance, to get read
and
write permissions,you add 4 (read) and 2 (write), thus getting 6
(read
and write). To get read and execute permissions, you add 4 (read)
and
1 (execute), thus getting 5 (read and execute).
Permissions Meaning
As long as you're the owner of a file, you can use the chmod
command
to set the permissions any way you like.
The UNIX system has the following default permissions for all
files
and directories:
How come that the file permissions for this file have been set to
644
What Unix does is it uses the value stored in a variable called
umask
to decide the default permissions. The umask value tells Unix which
of
the three permissions are to be denied rather than granted.The
current
value of umask can be easily determined by just typing umask.
$ umask
0022
Directory Permissions:
$ mkdir temp
$ cd temp
$ touch a b
$ pwd
/home/project/temp
$ ls -l
total 8
-rw-r--r-- 1 king development 0 Mar 18 18:56 a
-rw-r--r-- 1 king development 0 Mar 18 18:56 b
Labels: Article
Black 30 40
Red 31 41
Green 32 42
Yellow 33 43
Blue 34 44
Magenta 35 45
Cyan 36 46
White 37 47
The numbers in the above table work for xterm terminal.Result may
vary
for other terminal emulators.
The "\033[" begins the escape sequence.You can also use "\e["
instead
of "\033[". COLOR specifies a foreground color, according to the
table
above.The "m" terminates escape sequence, and text begins
immediately
after that.
The problem with above statement is that the blue color that starts
with the 32 color code is never switched back to the regular color,
so
any text you type after the prompt and even prompt also is still in
the
Green color.
echo -e "\033[0m"
Now you won't see anything new on the screen, as this echo
statement
was not passed any string to display. But it has done its job,
which
was to restore the normal viewing mode. Whatever yor type now will
be
avoid of any fancy effects.
0 Normal Characters
1 Bold Characters
4 Underlined Characters
5 Blinking Characters
Combining all these Escape Sequences, you can get more fancy
effect.
Use the following template for writing colored text on a colored
background.
The following shell script prints all the colors and codes on the
screen.
#!/bin/bash
# This script echoes colors and codes
Some examples:
Labels: Article
Like UNIX commands, shell scripts also accept arguments from the command
line.
They can, therefore, run non interactively and be used with redirection
and
pipelines.
Positional Parameters:
Arguments are passed from the command line into a shell program using the
positional parameters $1 through to $9. Each parameter corresponds to the
position of the argument on the command line.
The first argument is read by the shell into the parameter $1, The second
argument into $2, and so on. After $9, the arguments must be enclosed in
brackets, for example, ${10}, ${11}, ${12}.Some shells doesn't support
this
method. In that case, to refer to parameters with numbers greater than 9,
use
the shift command; this shifts the parameter list to the left.$1 is
lost,while
$2 becomes $1, $3 becomes $2, and so on. The inaccessible tenth parameter
becomes $9 and can then be referred to.
Example:
#!/bin/bash
# Call this script with at least 3 parameters, for example
# sh scriptname 1 2 3
exit 0
Output:
[root@localhost ~]# sh parameters.sh 47 9 34
first parameter is 47
Second parameter is 9
Third parameter is 34
first parameter is 4
Second parameter is 8
Third parameter is 3
The above command sets the value $1 with “Helping” , $2 with “hands” and
so on.
To verify, use echo statement to display their values.
$ echo $1 $2 $3 $4 $5 $6 $7
$ echo $*
$ echo $@
Observe that last two words in the output. These occurred in the output
because
at a time we can access only 9 positional parameters. When we tried to
refer to
$10 it was interpreted by the shell as if you wanted to out put the value
of $1
and a 0. Hence we got A0 in the output.
Does that mean the words following the ninth word have been lost? No. If
not,
then where have they gone?. They are very much there, safe with the shell
But to
reach them we must do the following.
$shift 4
$ echo $1 $2 $3 $4 $5 $6 $7 $8 $9
Now where have the first seven words gone? They have been shifted out.The
first
four words lost for ever, as we did not take the precaution to store them
else-
where. What should we have done is:
$ a=$1
$ b=$2
$ c=$3
$ d=$4
$ shift 4
$ echo $a $b $c $d $1 $2 $3 $4 $5 $6 $7 $8 $9
Note:In the Korn and bash shells you can refer directly to arguments
where
n is greater than 9 using braces. For example, to refer to the 57th
positional
parameter, use the notation ${57}.some shells may not support this method.
$ echo ${12}
real
$ echo ${13}
friend
$ echo ${!#}
friend
$* and $@
Let us look at the subtle difference between $* and $@.
Example:
#!/bin/bash
# Usage: sh arguments.sh fileA fileB temp\ file
cat $*
cat $@
exit 0
Output:
[root@localhost temp]# sh arguments.sh fileA fileB temp\ file
I LOVE INDIA
HELLO WORLD
I LOVE INDIA
HELLO WORLD
#!/bin/bash
# Usage: sh arguments.sh fileA fileB temp\ file
cat “$*”
cat “ $@”
exit 0
Output:
[root@localhost temp]# sh arguments.sh fileA fileB temp\ file
I LOVE INDIA
HELLO WORLD
On execution, the first of these commands would give an error since there
does
not exist a file with the name “fileA fileB temp file”. As against this,
the
second cat command would display the contents of the files fileA, fileB
and
“temp file”.So what you observed,when not enclosed within “” $* and $@
behaves
exactly similarly
Posted by venu k at 1:19 AM 8 comments
Labels: Article
Note:
In computing, a shebang (also called a hashbang, hashpling,
pound bang, or crunchbang) refers to the characters "#!" when
they are the first two characters in a text file. In a Unix-like
operating system, the program loader takes the presence of these
two characters as an indication that the file is a script, and
tries to execute that script using the interpreter specified by
the rest of the first line in the file. For instance, shell
scripts for the Bourne shell start with the first line:
#!/bin/sh
now change sha-bang line with #!/bin/ksh and execute the script
now change sha-bang line with #!/bin/zsh and execute the script
$sh temp
or
$bash temp
or
$zsh temp
Output:
My name is root
Users are king root root sai venu
OS name is Linux
Current shell is /bin/bash
#!/bin/bash
lines=$LINES
cols=$COLUMNS
echo $lines
echo $cols
Output:
$ sh sample
It prints nothing
Example:
$ export LINES COLUMNS
$ sh sample
24
80
Caution:
Try to unset variables at the end of the script. Otherwise
you will get add results. Variable and functions used in the
script will be alive after execution of the script.
Example:
create two files
cat > sample2
n=100
m=200
echo "n=$n m=$m"
ctrl+d
PATH=${PATH}:$HOME
Example:
First create a file “testscript” in home directory.
PATH=${PATH}:$HOME/bin
Labels: Article
Wednesday, October 7, 2009
Bash for Loop Syntax
A 'for loop' is a bash programming language statement which allows code to be repeatedly
executed. A for loop is classified as an iteration statement i.e. it is the repetition of a process
within a bash script.
For example, you can run UNIX command or task 5 times or read and process list of files using
a for loop. A for loop can be used at a shell prompt or within a shell script itself.
for VARIABLE in 1 2 3 4 5 .. N
do
command1
command2
commandN
done
Examples:
#!/bin/bah
for i in 1 2 3 4 5
do
echo "Welcome $i times"
done
#!/bin/bash
for i in $(seq 1 2 20)
do
echo "Welcome $i times"
done
To know more about “seq” command check manual using “man seq” command
#!/bin/bash
for i in {1..5}
do
echo "Welcome $i times"
done
Example:
#!/bin/bash
for (( c=1; c<=5; c++ ))
do
echo "Welcome $c times..." done
Labels: Article
Soft link( also called symbolic link): Soft link refers to "A symbolic path indicating the abstract location
of another file".
Soft Link is a symbolic link to the original file.(more like windows shortcuts)
Soft Links will have a different Inode value.
Any changes made to the soft link will reflect the original file and its hard links.
A soft link points to the original file. If you delete the original file, the soft link fails. It would
become dangling symbolic link.
If you delete the soft link, nothing will happen.
You can link a directory using soft link on same file system and also on other file system.
Soft links can cross file systems
Lets learn the difference with an example:
From the above output you can find inode number of both files are equal.
Now you find that inode value is different for the soft link and main file.
Note: Permission changes of original file reflects only on hard links. Its soft links permission
remains unchanged.
So removing the original file will affect the Soft link. The Soft link fails.Now it become a
dangling symbolic link(or broken link).Hard link is unaffected.
Now create main file "mainfile.txt" again and make its links as it is before it is
deleted.
Now lets try to edit hard link "hardlink.tst".Before that create soft link "softlink.txt" again.
From the above output its clear that changing the contents of the hard link will reflects on main
file and also reflect on soft link of main file.
Now lets try to remove main file then edit its soft link.
Soft link creates its main file.But it will not retain main file contents. It merely creates main file
"mainfile.txt" with data what you inserted in "softlink.txt".
Now hard link "hardlink.txt" will not have any relation with main file "mainfile.txt".Both files
now have unique inode value.
Now lets give a look on directories. How soft links and hard links behaves with directories:
Now create a directory named with temp and create some files in that directory.
Now try to create hard link and soft link for directory temp.
Above example clarifies that it's not possible to create hard link on directory but it is possible to
create soft link.
Note:
Like other files, a symbolic link has a separate directory entry with its own inode number. This
means that rm can remove a symbolic link even if its points to a directory(or even a device).
So lets try to remove symbolic link of a directory.In our above example "softtemp" is a symbolic
link for directory temp.
So it clears that we can remove directory symbolic link with rm command just like a file. But
don't add "/" at the end of link(If you use tab to complete file name at command prompt it
automatically adds / at the end of link if it points to a directory).
Observations:
You can link multiple files (i.e., create a link for each), but then the destination filename must be
a directory.
Ex: ln chap?? project project is a directory
When you create hard link, The link count of file increases one. So based on link count you can
find how many instances of a file exist in your system.
So a file is considered to be completely removed from the system when its link count drops to
zero
Many UNIX/Linux commands are linked.
Ex:
If you want to create symbolic link of a file in other directory your source file path must be
absolute.
You can identify symbolic links by the character "l" seen in the permission field.
Observe that the size of the symbolic link is equal to length of the path name it contains.
To view the permissions of the file or directory that the symbolic link references, use L
option with ls -l (i.e. ls -lL )
Ex: [root@localhost scripts]# ls -l /usr/bin/gzip
lrwxrwxrwx 1 root root 14 2008-11-11 03:10 /usr/bin/gzip -> ../../bin/gzip
[root@localhost scripts]# ls -lL /usr/bin/gzip
-rwxr-xr-x 1 root root 64524 2008-02-22 02:55 /usr/bin/gzip
Labels: Article
A variable declared as local is one that is visible only within the block of code in which it appears.
It has local "scope." In a function, a local variable has meaning only within that function block.
Ex:
local variable name
func ()
{
local loc_var=23
# Declared as local variable.
# Uses the 'local' builtin.
echo "\"loc_var\" in function = $loc_var"
global_var=999
func
# Now, to see if local variable "loc_var" exists outside function.
Before a function is called, all variables declared within the function are invisible outside the
body of the function, not just those explicitly declared as local
func ()
{
global_var=37
func
echo "global_var = $global_var"
# global_var = 37 Has been set by function call.
foo ()
{
FOO="bar"
}
bar ()
{
foo
echo $FOO
}
bar
# Prints bar
However . . .
foo (){
declare FOO="bar"
}
bar ()
{
foo
echo $FOO
}
bar
# Prints nothing.
clear
n=$1
echo -e "\033[47m" #used for colourizing output
for ((row=1;row<=n;row++))
do
spaces=$((n-row))
stars=$((2*$row - 1))
for ((i=1;i<=spaces;i++))
do
echo -n ' '
done
for ((i=1;i<=stars;i++))
do
echo -e '\033[43m*\033[47m\c'
done
for ((i=1;i<=spaces;i++))
do
echo -n ' '
done
echo
done
echo -e "\033[0m"
unset n i spaces stars row
# Unset variables is a good programming practice
Output:
[root@localhost blog]# sh for_pyramid 22
1. function triline() {
2. item=1 # keep track of what to 'store' next
3. linesofar="" # keep track of what is already stored
4. while [ "$item" -le "$1" ]; do # standard while loop starting from
arg1
5. linesofar="$linesofar $item" # store the next item
6. item=$(( item + 1 )) # advance the counter
7. done
8. item=$(( item - 1 )) # the counter is too big. Reduce
9. while [ "$item" -gt 1 ] ; do # standard while loop down to 1
10. item=$(( item - 1 )) # pre-decrement
11. linesofar="$linesofar $item" # store the next item
12. done
13. echo $linesofar # echo the result
14. }
griswolf
Reputation Points: 174
Solved Threads: 106
Practically a Master Poster
Offline
621 posts
since Apr 2010
Permalink
Oct 7th, 2010
0