Beruflich Dokumente
Kultur Dokumente
Share
More
Next Blog
Create Blog
Sign In
#!/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 0 ] # Look for parameters supplied or not then echo "$0: missing file operand" exit 1 fi if [ $# -eq 1 ] # Look for exactly one parameter then echo "$0 : missing destination file operand after '$1'" exit 1 fi 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
?S
Popular Posts How to Read a File Line by Line in a Shell Script How to Pass Arguments to Shell Script Math in Shell Scripts Shell Colors: colorizing shell scripts
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 # ################################################################### Seek=0 # skip BLOCKS bs-sized blocks at start of output Skip=0 # skip BLOCKS bs-sized blocks at start of input Bsize=128000 # block size size=`stat -c %s "$Source"` # Bellow 25MB files copied directly with copy command # If you want progress bar for < 25MB files also, remove bellow # if block if [ $size -lt 25000000 ] then cp "$Source" "$Dest" exit 0 fi blocks=$((size/Bsize)) lastblock=$((size%Bsize)) # total blocks of input file # last block, which size < $Bsize
"
# If last block size is > 0 then add 1 block to existing blocks. if [ $lastblock -gt 0 ] then let blocks++ fi # I am dividing screen width 60 as 20 parts.Each part is filled # with a colour after each iteration. # Make blocks count dividable by 20. addblocks=$((blocks%20)) if [ $addblocks -gt 0 ] then adjustblocks=$((20-addblocks)) blocks=$((blocks+adjustblocks)) fi
Count=$((blocks/20)) # Count variable contain number of blocks to be copied for # each iteration ################################################################### # MAIN PROGRAM STARTS HERE # ################################################################### printf "\e[40m\e[43m%60s\n\e[A" " " for ((i=1;i<=20;i++)) do dd if="$Source" of="$Dest" bs=128kB seek=$Seek skip=$Skip \ count=$Count 2>/dev/null Skip=$((Skip+$Count)) Seek=$((Seek+$Count)) j=$((j+3))
Screen Shot2:
Screen Shot3:
Posted by venu k at 10:46 PM 2 comments Labels: Shell Scripts Tuesday, November 24, 2009
Posted by venu k at 2:20 PM 3 comments Labels: Linux Fun Tuesday, November 17, 2009
"********BAD ARGUMENTS**********" "Usage: scriptname <Range Value >" " or " "Usage: scriptname <Start Range Value> <End Range Value>" 1
################# ARGUMENTS CHECKING ################# [ [ [ [ $# $# $# $1 -gt -eq -eq -lt 2 1 2 2 -o $# -lt 1 ] && Usage ] && Bnum=2 && Enum=$1 ] && Bnum=$1 Enum=$2 && [ $1 -gt $2 ] && Usage ] && Bnum=2
############### MAIN PROGRAM STARTS HERE ############# count=1 while [ $Bnum -le $Enum ] do num=$Bnum Prime="yes" i=1
#while [ $i -lt $((num/2)) ] while [ $((i*i)) -lt $((num-1)) ] do let i++ if [ $((num%i)) -eq 0 ] then Prime="no" break fi done
[ "$Prime" = "yes" ] && printf "%5d " $num && let count++ # count is used to print 10 values in a row [ $count -eq 11 ] && count=1 && let Bnum++ done echo
OUTPUT:
echo
$ ./primenumbers.sh 1 350 2 31 73 127 179 233 283 3 37 79 131 181 239 293 5 41 83 137 191 241 307 7 43 89 139 193 251 311 11 47 97 149 197 257 313 13 53 101 151 199 263 317 17 59 103 157 211 269 331 19 61 107 163 223 271 337 23 67 109 167 227 277 347 29 71 113 173 229 281 349
$ ./primenumbers.sh 1900 2500 1901 1993 2063 2131 2221 2293 2371 2437 1907 1997 2069 2137 2237 2297 2377 2441 1913 1999 2081 2141 2239 2309 2381 2447 1931 2003 2083 2143 2243 2311 2383 2459 1933 2011 2087 2153 2251 2333 2389 2467 1949 2017 2089 2161 2267 2339 2393 2473 1951 2027 2099 2179 2269 2341 2399 2477 1973 2029 2111 2203 2273 2347 2411 1979 2039 2113 2207 2281 2351 2417 1987 2053 2129 2213 2287 2357 2423
$ ./primenumbers.sh 200 2 31 73 127 179 3 37 79 131 181 5 41 83 137 191 7 43 89 139 193 11 47 97 149 197 13 53 101 151 199 17 59 103 157 19 61 107 163 23 67 109 167 29 71 113 173
[root@localhost shell]# ./primenumbers.sh 200 100 ********BAD ARGUMENTS********** Usage: scriptname <Range Value> or Usage: scriptname <Start Range Value> <End Range Value>
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.
Recommend this on Google
Method 1:
Now most people who write finding prime number in shell script(Almost in all languages) may start with something simple, like: #!/bin/bash # SCRIPT: prime1.sh # USAGE : ./prime1.sh # PURPOSE: Finds whether given number is prime or not ##################################################################### echo -n "Enter a number: " read num i=2 while [ $i -lt $num ] do if [ `expr $num % $i` -eq 0 ] then echo "$num is not a prime number" echo "Since it is divisible by $i" exit fi i=`expr $i + 1` done echo "$num is a prime number " Output: [root@venu ]# ./prime1.sh Enter a number: 1879 1879 is a prime number [root@venu ]# ./prime1.sh Enter a number: 119 119 is not a prime number Since it is divisible by 7 Using here string you can supply input non interactively. [root@venu ]# ./prime1.sh <<<2239 Enter a number: 2239 is a prime number However, rather than testing all m up to n1, it is only necessary to test m up to sqrt n : if n is composite then it can be factored into two values,at least one of which must be less than or equal to sqrt n . Don't use method 1, it is very worst method, I hope that you will agree with me at the end of this post.
Method 2a:
#!/bin/bash # SCRIPT: prime2a.sh
# USAGE : ./prime2a.sh # PURPOSE: Finds whether given number is prime or not ##################################################################### echo -n "Enter a number: " read num ##################################################################### # Integer Validation # ##################################################################### # If you are a expr $num + 1 beginner you can skip this integer validation block. &> /dev/null
if [ $? -ne 0 ] then echo "Sorry, You supplied non numerical value" exit 1 fi [ $num -lt 2 ] && echo "Values < 2 are not prime numbers" && exit 1 ##################################################################### # Main Script Starts Here # ##################################################################### i=2 sqrtofnum=`echo "sqrt($num)"|bc` while [ $i -le $sqrtofnum ] do if [ `expr $num % $i` -eq 0 ] then echo "$num is not a prime number" echo "Since it is divisible by $i" exit fi let i++ done echo "$num is a prime number " Output: [root@venu ]# ./prime2a.sh <<<169 Enter a number: 169 is not a prime number Since it is divisible by 13 [root@venu ]# ./prime2a.sh <<<3181 Enter a number: 3181 is a prime number
Method 2b:
#!/bin/bash # SCRIPT: prime2b.sh # USAGE : ./prime2b.sh # PURPOSE: Finds whether given number is prime or not ##################################################################### echo -n "Enter a number: " read num
##################################################################### # Integer Validation # ##################################################################### # If you are a beginner you can skip integer validation block. expr $num + 1 &> /dev/null
if [ $? -ne 0 ] then echo "Sorry, You supplied non numerical value" exit 1 fi [ $num -lt 2 ] && echo "Values < 2 are not prime numbers" && exit 1 ##################################################################### # Main Script Starts Here # ##################################################################### i=1 newnum=$((num-1)) while [ $((i*i)) -lt $newnum ] do let i++ if [ `expr $num % $i` -eq 0 ] then echo "$num is not a prime number" echo "Since it is divisible by $i" exit fi done echo "$num is a prime number " Output: [root@venu ]# ./prime2b.sh <<<361 Enter a number: 361 is not a prime number Since it is divisible by 19 [root@venu ]# ./prime2b.sh <<<3571 Enter a number: 3571 is a prime number
Method 3a:
#!/bin/bash # SCRIPT: prime3a.sh < Number to check > # USAGE : ./prime3a.sh # PURPOSE: Finds whether a given number is prime or not. ##################################################################### # ARGUMENTS CHECKING # ##################################################################### # If you are a beginner you can skip Arguments checking part. if [ $# -ne 1 ] then echo "Usage: scriptname <number to check>" exit 1 fi expr $1 + 1 &> /dev/null
if [ $? -ne 0 ] then echo "Sorry, You supplied non numerical value" exit 1 fi [ $1 -lt 2 ] && echo "Values < 2 are not prime numbers" && exit 1 ##################################################################### # MAIN PROGRAM STARTS HERE # ##################################################################### num=$1 sqrtofnum=`echo "sqrt($num)" | bc ` i=2 while [ $i -le $sqrtofnum ] do if [ $(((num/i)*i)) -eq $num ] then echo "$num is not a prime number" echo "Since it is divisible by $i" exit 0 fi let i++ done # you can also use i=`expr $i + 1`
echo "$num is a prime number" Output: [root@venu ]# ./prime3a.sh 529 529 is not a prime number Since it is divisible by 23 [root@venu ]# ./prime3a.sh 3571 3571 is a prime number
Method 3b:
#!/bin/bash # SCRIPT: prime3b.sh # USAGE : ./prime3b.sh <Number to check > # PURPOSE: Finds whether a given number is prime or not. ##################################################################### # ARGUMENTS CHECKING # ##################################################################### # If you are a beginner you can skip Arguments checking part. if [ $# -ne 1 ] then echo "Usage: scriptname <number to check>" exit 1 fi expr $1 + 1 &> /dev/null if [ $? -ne 0 ] then echo "Sorry, You supplied non numerical value" exit 1
fi [ $1 -lt 2 ] && echo "Values < 2 are not prime numbers" && exit 1 ##################################################################### # MAIN PROGRAM STARTS HERE # ##################################################################### num=$1 newnum=$((num-1)) i=1 while [ $((i*i)) -lt $newnum ] do let i++ # you can also use i=`expr $i + 1`
if [ $(((num/i)*i)) -eq $num ] then echo "$num is not a prime number" echo "Since it is divisible by $i" exit 0 fi done echo "$num is a prime number" Output: [root@venu ]# ./prime3b.sh 12009 12009 is not a prime number Since it is divisible by 3 [root@venu ]# ./prime3b.sh 16127 16127 is a prime number Now using time command to test which script runs fast. OUTPUT 1: [root@venu ]# time sh prime1.sh <<<99991 Enter a number: 99991 is a prime number real 5m6.590s user 1m13.882s sys 3m29.807s [root@venu ]# time sh prime2a.sh <<<99991 Enter a number: 99991 is a prime number real 0m0.558s user 0m0.159s sys 0m0.409s [root@venu ]# time sh prime2b.sh <<<99991 Enter a number: 99991 is a prime number real 0m0.534s user 0m0.141s sys 0m0.405s [root@venu ]# time sh prime3a.sh 99991 99991 is a prime number real 0m0.037s user 0m0.034s sys 0m0.003s [root@venu ]# time sh prime3b.sh 99991
OUTPUT 2: [root@venu ]# time sh prime1.sh <<<319993 Enter a number: 319993 is a prime number real 16m44.993s user 4m3.943s sys 12m17.365s [root@venu ]# time sh prime2a.sh <<<319993 Enter a number: 319993 is a prime number real 0m0.883s user 0m0.218s sys 0m0.529s [root@venu ]# time sh prime2b.sh <<<319993 Enter a number: 319993 is a prime number real 0m0.739s user 0m0.238s sys 0m0.494s [root@venu ]# time sh prime3a.sh 319993 319993 is a prime number real 0m0.072s user 0m0.054s sys 0m0.007s [root@venu ]# time sh prime3b.sh 319993 319993 is a prime number real user sys 0m0.089s 0m0.061s 0m0.008s
I hope, now you understood, Just one line of code makes the difference. Method 1 takes more and more time to find prime number.
Posted by venu k at 8:46 AM 7 comments Labels: Beginners Scripts, Shell Scripts Sunday, November 15, 2009
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 echo "first parameter is $1" echo "Second parameter is $2" echo "Third parameter is $3" exit 0 Output: [root@localhost ~]# sh parameters.sh 47 9 34 first parameter is 47 Second parameter is 9 Third parameter is 34 [root@localhost ~]# sh parameters.sh 4 8 3 first parameter is 4 Second parameter is 8 Third parameter is 3
In addition to these positional parameters, there are a few other special parameters used by shell.Their significance is noted bellow. $* - It stores the complete set of positional parameters as a single string. $@ - Same as $*, But there is subtle difference when enclosed in double quotes. $# - It is set to the number of arguments specified.This lets you design scripts that check whether the right number of arguments have been entered. $0 - Refers to the name of the script itself.
values to the positional parameters, using the set command. $ set Helping hands are holier than praying lips 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 Helping hands are holier than praying lips You can simply use $* or $@ $ echo $* Helping hands are holier than praying lips $ echo $@ Helping hands are holier than praying lips
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 when one is in trouble is a real friend
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 elsewhere. What should we have done is: $ set A friend who helps when one is in trouble is a real friend $ a=$1
$ b=$2 $ c=$3 $ d=$4 $ shift 4 $ echo $a $b $c $d $1 $2 $3 $4 $5 $6 $7 $8 $9 A friend who helps when one is in trouble is a real friend
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.
$ set A friend who helps when one is in trouble is a real friend $ echo ${12} real $ echo ${13} friend
Bracket notation for positional parameters leads to a fairly simple way of referencing the last argument passed to a script on the command line. $ echo ${!#} friend
$* and $@
Let us look at the subtle difference between $* and $@. First create three files cat > fileA I LOVE INDIA Ctrl+d cat > fileB HELLO WORLD Ctrl+d cat > temp\ file This file name contains blank space Ctrl+d fileA, fileB, file temp
Example:
#!/bin/bash # Usage: sh arguments.sh fileA fileB temp\ file
echo -e "\033[1mDisplay files content using \$* \033[0m" cat $* echo -e "\033[1mDisplay files content using \$@ \033[0m" cat $@ exit 0 Run the script with file names as arguments. Output: [root@localhost ~]# sh arguments.sh fileA fileB temp\ file Display files content using $* I LOVE INDIA HELLO WORLD cat: temp: No such file or directory cat: file: No such file or directory Display files content using $@ I LOVE INDIA HELLO WORLD cat: temp: No such file or directory cat: file: No such file or directory So there is no difference between cat $* and cat $@. Modify arguments.sh script as #!/bin/bash # Usage: sh arguments.sh fileA fileB temp\ file echo -e "\033[1mDisplay files content using \"\$*\" \033[0m" cat "$*" echo -e "\033[1mDisplay files content cat "$@" exit 0 Now again run the script with file names as arguments. Output: [root@localhost ~]# sh arguments.sh fileA fileB temp\ file Display files content using "$*" cat: fileA fileB temp file: No such file or directory Display files content using "$@" I LOVE INDIA HELLO WORLD This file name contain blank space Now there is a difference, the two cat commands would become: cat fileA fileB temp file cat fileA fileB 'temp file' 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 using \"\$@\" \033[0m"
temp file. So what you observed ,when not enclosed within "double quotes" $* and $@ behaves exactly similarly, and when enclosed in "double quotes" there is a subtle difference.
Recommend this on Google
Posted by venu k at 1:19 AM 35 comments Labels: Article Thursday, November 12, 2009
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`} if [ $YEAR -lt 1 -o $YEAR -gt 9999 ] then echo "Illegal Year Value: Use 1-9999" exit 1 fi ##################################################### ############### 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 if [ ${rem2} = "0" -a ${rem3} != "0" ] then echo "$YEAR Is Not A Leap Year" exit fi if [ ${rem1} = "0" -a ${rem2} != "0" ] then
echo "$YEAR Is A Leap Year" else echo "$YEAR Is Not A Leap Year" fi OUTPUT: [root@ localhost shell]# ./leapyear.sh 2009 Is Not A Leap Year [root@localhost shell]# ./leapyear.sh 2100 2100 Is Not A Leap Year [root@localhost shell]# ./leapyear.sh 2104 2104 Is A Leap Year [root@localhost shell]# ./leapyear.sh 21000 Illegal Year Value: Use 1-9999 [root@localhost shell]# ./leapyear.sh 1996 1996 Is A Leap Year
Recommend this on Google
Posted by venu k at 1:17 AM 2 comments Labels: Beginners Scripts Monday, November 2, 2009
# Total blocks of input file # Last block, which size < $Bsize
# If last block size is > 0 then add 1 block to existing blocks. if [ $lastblock -gt 0 ] then let blocks++ fi # I am dividing screen width 60 as 20 parts.Each part is filled with color # after each iteration. # Make blocks count dividable by 20. addblocks=$((blocks%20)) if [ $addblocks -gt 0 ] then adjustblocks=$((20-addblocks)) blocks=$((blocks+adjustblocks)) fi Count=$((blocks/20)) # Count variable contain number of blocks to be copied for each iteration ############################################### # MAIN PROGRAM STARTS HERE # ############################################### printf "\e[40m\e[43m%60s\n\e[A" " " for ((i=1;i<=20;i++)) do dd if=$1 of=$$.temp bs=128kB seek=$Seek skip=$Skip count=$Count 2>/dev/null Skip=$((Skip+$Count)) Seek=$((Seek+$Count)) j=$((j+3)) # 60/20 each part is 3 chars length printf "\e[40m\e[7m%${j}s\n\e[A" " " # echo -e "\033[7m \c" # sleep 1 # Uncomment it for small files 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.
Recommend this on Google
Posted by venu k at 4:21 AM 2 comments Labels: Shell Scripts Sunday, November 1, 2009
# Number of characters per line # New file to create # Initialize to a zero-sized file # Total number of lines to create # Character counter # Character to write to the file
while ((LINE_COUNT < TOTAL_LINES)) do CHAR_COUNT=0 # Initialize the CHAR_COUNT to zero on every new line while ((CHAR_COUNT < LINE_LENGTH)) # Each line is fixed length do echo -e "$CHAR\c" >> $OUT_FILE # Echo a single character let CHAR_COUNT++ # Increment the character counter done let LINE_COUNT++ echo>>$OUT_FILE done
Recommend this on Google
Posted by venu k at 11:56 AM 3 comments Labels: Beginners Scripts Tuesday, October 27, 2009
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 } # # # # # # Bash function returns integer value only. But maximum integer value that bash can handle is 9223372036854775807. An operation that takes a variable outside these limits will give an erroneous result. That's why I redirected stderror output to /dev/null
# Main program starts here. if [ $# -ne 1 ] then echo "Invalid Arguments" echo "Usage: ./fact2.sh Number " exit 1 fi factorial $1 echo "Factorial of $1 is $Factorial" 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 [root@localhost shell]# ./fact2 Invalid Arguments Usage: ./fact2.sh Number [root@localhost shell]# ./fact2 7 Factorial of 7 is 5040 [root@localhost shell]# ./fact2 33 Factorial of 33 is 8683317618811886495518194401280000000
Posted by venu k at 8:41 AM 15 comments Labels: Beginners Scripts Monday, October 26, 2009
n=${1-10} # If command line argument not supplied default is 10 t=`expr $((2*$n - 1 ))` a=$n b=$(($a+1)) for (( i=1 ; i<=$n ;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 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
"
Posted by venu k at 9:50 AM 0 comments Labels: Beginners Scripts Saturday, October 10, 2009
Note: Script path should be relative to the current directory then only this method works. If you want to execute a script in the current directory you use ./scriptname. In fact if you want to execute a script in the parent directory of your current location you can use ../scriptname , as . means current and .. means parent. Run temp script. [root@localhost shell]# ./temp My name is root Users are root root OS name is Linux current shell is /bin/bash now change sha-bang line with #!/bin/ksh and execute the script [root@localhost shell]# ./temp bash: ./temp: /bin/ksh: bad interpreter: No such file or directory now change sha-bang line with #!/bin/zsh and execute the script [root@localhost shell]# ./temp My name is root Users are root root OS name is Linux current shell is /bin/bash So wrong path to interpreter or bad interpreter gives error message.
you can execute the bash script by specifying the filename as an argument to the bash,sh,zsh commands. This is a bad way to call a script, since it will override the #! at the beginning of the script.Depending on command you used, current shell spawns relative subshell. $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 Note: It is good to use proper command. Suppose your script is korn shell script,then run it as: ksh temp Caution: In this method shell runs script in sub shell. So you can't access some shell builtin variable values. For example run bellow shell script: #!/bin/bash lines=$LINES cols=$COLUMNS echo $lines echo $cols Output: $ sh sample It prints nothing Note: To solve this problem export current shell variables using export command.Before executing script, export all variables you need. Example: $ export LINES COLUMNS $ sh sample 24 80
[root@localhost shell]# source temp My name is root Users are king root root sai venu OS name is Linux current shell is /bin/bash 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 cat > sample3 n=$((n+m)) m=$((m+25)) echo "n=$n m=$m" ctrl+d Execute scripts using sh command [root@localhost shell]# sh sample2 n=100 m=200 [root@localhost shell]# sh sample3 n=0 m=25 Now execute scripts using . Or source command [root@localhost shell]# . sample2 n=100 m=200 [root@localhost shell]# . sample3 n=300 m=225 So be careful. Try to unset variables at the end of the script.
My name is root Users are king root root sai venu OS name is Linux current shell is /bin/bash Suppose you changed temp script name to ls, what will happen, which result you will get. [root@localhost ~]# mv temp ls [root@localhost ~]# ls Desktop ls sample sample2 sample3 So you will get ls command output. Why ? When you type name of any command at $ prompt, what shell do is it first look that command in it's internal part(called as internal command,which is part of shell itself, and always available to execute),if found as internal command shell will execute it, if not found then shell will look PATH setting, and try to find our requested commands executable file in all of the directories mentioned in PATH settings,if found it will execute it, other wise it will give message bash:XXXX:command not found. So don't use command name as shell script. Note: If you have two different files with same name in different directories, which file will execute? The directory which comes first in PATH setting will be executed. Example: First create a file testscript in home directory. $ cat > testscript whoami ctrl+d Then create a directory bin in home directory $ mkdir bin Now create a file with same name testscript in $ cd bin $ cat > testscript date ctrl+d
bin dirctory.
Then add bin directory to PATH variable.If your bin directory already in PATH setting leave it. PATH=${PATH}:$HOME/bin now check your path settings [root@localhost ~]# echo $PATH /usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin: /usr/lib/ccache:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/ bin:/usr/bin:/bin:/root/bin:/root /root and /root/bin added to your PATH. I added /root/bin directory before /root directory. now execute testscript script
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 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:
done Using seq command #!/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 Bash 3.0+ version supports following syntax also #!/bin/bash for i in {1..5} do echo "Welcome $i times" done
row=1; echo -e "\033[47m" while [[ $row -le $n ]] do loop=1; spaces=$((n-row)) stars=$((2*row - 1)) while [[ $loop -le $spaces ]] do echo -n ' ' let loop++ done loop=1; while [[ $loop -le $stars ]] do echo -e '\033[43m*\033[47m\c' let loop++ done loop=1; while [[ $loop -le $spaces ]] do echo -n ' ' let loop++ done echo let row++ done echo -e "\033[0m" unset row loop spaces stars n Output: [root@localhost blog ]# sh while_pyramid 22
# 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 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
Posted by venu k at 5:35 AM 4 comments Labels: Beginners Scripts Tuesday, September 22, 2009
} 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
Recommend this on Google
# 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):
Recommend this on Google
Posted by venu k at 9:31 PM 7 comments Labels: Shell Scripts 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]#
Recommend this on Google
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 is a valid user [root@localhost shell]# sh validuser.sh venuk is not a valid user [root@localhost shell]# sh validuser.sh root is a valid user [root@localhost shell]# sh validuser.sh roott is not a valid user [root@localhost shell]#
Posted by venu k at 10:11 AM 8 comments Labels: Shell Scripts 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
Recommend this on Google
Posted by venu k at 1:25 PM 2 comments Labels: Shell Scripts Sunday, August 23, 2009
What is the difference between Hard Link and Soft Link in Linux
Hard link: Hard link refers to "The specific location of physical data".
Hard Link is a mirror copy of the original file. Hard links share the same inode. Any changes made to the original or Hard linked file will reflect the other. Even if you delete any one of the files, nothing will happen to the other hard links. But soft link which points to deleted hard link become a dangling soft link. You can't link a directory even within the same file system. Hard links can't cross file systems. 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: First create a file named with "mainfile.txt"
From the above output you can find inode number of both files are equal. Now create a soft link named with "softlink.txt"
Now you find that inode value is different for the soft link and main file. But equal for the hard link and main file. Contents of all files before editing
From the above output it clarifies that, changes of main file reflects its soft and hard links. Note: Permission changes of original file reflects only on hard links. Its soft links permission remains unchanged. Now lets remove main file "mainfile.txt"
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. let now try to remove soft link "softlink.txt".
It clarifies that deletion of soft link will not affect the main file and its hard links. 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 edit the soft link "softlink.txt".
From the above output its clear that changing the contents of soft link will reflects on main file and also on all links of main file. Now lets try to remove main file then edit its soft link.
Some strange result. 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: [root@localhost ~]# ls -li /usr/bin/gzip 499116 lrwxrwxrwx 1 root root 14 2008-11-11 03:10 /usr/bin/gzip ->../../bin/gzip
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