Nothing Special   »   [go: up one dir, main page]

SH 2

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 21

How to debug shell script?

--------------------------
in commandline -> bash -x filename.sh ->(1)

+ <== debugging prompt

set -x
..
..
set +x
---------------------------------------------------------------------------
Logical operators
--------------------
|->In Single conditional statement,test more than one condition
----------------------------- ======================== //use logical
operator

example:
----------
test port number 501-599
test your working shell is sh (or) bash anyshell is matched ->OK
|
test your hostname and kernel
| |
------ --------
host01 host02 | |
Sunos Linux

logical and => -a


---
Condition1 Condition2 Result
True True True
True False False
False True False
False False False

port=550

$port -gt 500 ->(1)


} => [ $port -gt 500 -a $port -lt 600 ]
$port -lt 600 ->(2)

--------------

logical or => -o
---
Condition1 Condition2 Result
True True True
True False True
False True True
False False False

sh_var="sh"

[ $sh_var == "bash" -o $sh_var == "sh" ]

logical not => !

opp.of testing => test say True ->! ->False


test say False ->! ->True

Write a shell script


read a user name - test user name is admin
|
if not a admin -> display message your not admin.

read -p "Enter a login name:" name

if [ $name == "admin" ]
then
there is no action
else
echo "Sorry your not admin"
fi
Vs

if ! [ $name == "admin" ]
then
echo "Sorry your not admin"
fi
----------------------------------------------------------------------------
Write a shell script

read a app port number from <STDIN>


|
test input port number range 501-599 => initialize app name is App-1
test input port number is 5000 (or) 8080 => initialize app name is Flask
test input port number is 9090 => initialize app name is prometheus
|
default app name is - demoApp ;default port number is 9091
|
display Appname and app running port number.

read -p "Enter a port number:" port

if [ $port -gt 500 -a $port -lt 600 ]


then
app="App-1"
elif [ $port -eq 5000 -o $port -eq 8080 ]
then
app="Flask"
elif [ $port -eq 9090 ]
then
app="prometheus"
else
echo "Sorry your input port:$port is not matched"
echo "default initialization is:"
app="demoApp"
port=9091
fi
echo "App name is:$app Running port number is:$port"

-----------------------------------------------------------------------------------
-----------
[ `whoami` == "root" -a `hostname` == "host01" -a `ps -e|wc -l` -gt 100 -a $p ==
"xend" ]
---------------- -------------------- --------------------
------------

[[ ]] <== expanded test operator


_____
|<== we can use && || operators

[[ `whoami` == "root" && `hostname` == "host01" ]] && [[ `ps -e|wc -l` -gt 100 &&
$p == "xend" ]]

if [[ `whoami` == "root" && `hostname` == "host01" ]] && [[ `ps -e|wc -l` -gt 100
&& $p == "xend" ]]
then
....
else
....
fi

[[ 100 -gt 50 && "abc" == "abc" ]] && [[ 560 -gt 500 && 600 -eq 600 ]]

# [ 100 -gt 50 -a "abc" == "abc" -a 560 -gt 500 -a 600 -eq 600 ]
#echo $?
0
#[ 100 -gt 50 -a "abc" == "abc" ] -a [ 560 -gt 500 -a 600 -eq 600 ]
bash: [: too many arguments
#
#[[ 100 -gt 50 && "abc" == "abc" ]] && [[ 560 -gt 500 && 600 -eq 600 ]]
#echo $?
0
#sh_var="ksh"
#
#[[ $sh_var == "bash" || $sh_var == "ksh" ]]
#echo $?
0
#[ $sh_var == "bash" -o $sh_var == "ksh" ]
#echo $?
0
#[[ 100 -gt 50 && "abc" == "Abc" ]] && [[ 560 -gt 500 && 600 -eq 600 ]]
#echo $?
1
-----------------------------------------------------------------------------------
----------------------------------------------
recap
-----
-> arithmetic
-> relational
-> logical
|
-> file test operators
--------------------
|-> file types
|-> file mode (operation) - read(-r) write(-w) execute(-x)

file types
------------
1. Regular file (or) Ordinary file (-f)
ASCII / Text - user can able to read/understand (ex: p1.sh p1.java p1.c
p1.log etc.,)
ELF - user can't able to read/understand (ex: unix/linux commands)
2. Directory file (-d)

3. Link file (or) symbolic link (or) soft link ln -s source target (-l (or) -h)

4. device file (/dev)


|
|-> character type device (ex: terminal,printer,keyboard ) (-c)
|-> block type device (ex: Harddisk,USB,CDROM,DM ) (-b)

5. named pipe (or) FIFO (ex: mkfifo <filename> ) ( -p )


6. socket ( -S) <== upper case 'S'

[<space>FileTestOperator<space>inputFile<space>]

Test input file is reg.file or not ?


|

if [ -f filename ]
then
....
else
....
fi

Test input file is executable file or not?

if [ -x filename ]
then
...
else
...
fi

-e <== file is existing or not

[ -e /etc ]
echo $? ------>0

[ -e /etc/passwd ]
echo $? -------------->0

cat pop.log {Enter}


No such file (or) directory pop.log

[ -e pop.log ]
echo $? ------------>1

______________________________________________________________________
Q. Write a shell script

step 1: read a input filename from <STDIN>


| (-e)
step 2: test input file is exists or not
| |-> file is not exists
| (-f)
test your input file is reg.file or not
________ ===
|
ls -l <filename>
(-d)
test your input file is directory file
----------
ls -ld <filename>
|
|
using file command - determine file type
---------------------------------------------------------------------------
read -p "Enter a filename:" fname

if [ -e $fname ]
then
if [ -f $fname ]
then
echo "File: $fname is a reg.file"
ls -l $fname
elif [ -d $fname ]
then
echo "File: $fname is a directory file"
ls -ld $fname
else
echo "File:$fname is exists"
file $fname
fi
else
echo "Sorry file $fname is not exists"
exit
fi

Q. Write a shell script

step 1: read a directory file name


|
step 2: test input directory is exists or not
| |->using mkdir command - create a newdirectory
ls -ld <dir> -----
|-> $? - display directory creation
message
---------------------------------------------------------------------------------
read -p "Enter a directory name:" dname

if [ -d $dname ]
then
echo "directory $dname is exists"
ls -ld $dname
else
mkdir $dname
if [ $? -eq 0 ]
then
echo "Directory $dname is created"
ls -ld $dname
else
echo "Directory $dname creation is failed"
fi
fi

-----------------------------------------------------------------------------------
--------
case statement
--------------
|-> Code block
|-> execute only one time

Syntax:-
---------
case value in
pattern1) pattern1 operation
;;
pattern2) pattern2 operation
;;
pattern3) pattern3 operation
;;
..
patternN) patternN operation
;;
*) default operation
esac

# case in esac - keywords

Note: if..elif with == (or) -eq operator logic is same as case statement

server="Linux"

if [ $server == "unix" ] case $server in


then unix) echo "Matched-1" ;;
echo "Matched-1" aix) echo "Matched-2"
elif [ $server == "aix" ] ;;
then => Linux) echo "Matched-3" ;;
echo "Matched-2" Sunos) echo "Matched-4" ;;
elif [ $server == "Linux" ] *) echo "Not-Matched"
then esac
echo "Matched-3"
elif [ $server == "Sunos" ]
then
echo "Matched-4"
else
echo "Not-Matched"
fi

bash -x mc1.sh bash -x mc2.sh

-------------------------------------------------------------------

if [ condition ]
then
case $variable in
pattern1) .. ;;
pattern2) .. ;;
..
*) ...
esac
else
....
fi

case $variable in
pattern1) if [ condition ]
then
...
else
...
fi
;;
pattern2) if [ condition1 ]
then
...
elif [ condition2 ]
then
..
..
else
..
fi
;;
..
*) ....
esac

-----
write a shell script
---------------------
step 1: create a menu list in below format (use - echo with multiline string)

******** Select your package *********


* *
* 1. gcc *
* 2. shell name *
* 3. App *
* 4. system info *
* 5. Quit *
* *
**************************************

step 2: read a choice from user (<STDIN>)

step 3:
gcc => read a compiler version from <STDIN>
test version 4-6
|
shell name =>read a shell name from <STDIN>
test shell is sh (or) ksh (or) bash //any one shell is matched
|
App => read a port number from <STDIN>
test a port number 1001-1999

|
system info => display kernel version,login name,hostname,Today date

echo "

******** Select your package *********


* *
* 1. gcc *
* 2. shell name *
* 3. App *
* 4. system info *
* 5. Quit *
* *
************************************** "

read -p "Enter your choice:" choice


case $choice in
1) read -p "Enter your gcc version:" gv
if [ $gv -ge 4 -a $gv -le 6 ]
then
echo "selected gcc version is $gv"
else
echo "Select 4-6 version"
fi
;;
2) read -p "Enter a shell name:" sh_var
case $sh_var in
sh|ksh|bash) echo "selected shell name is:$sh_var" ;;
*) echo "Sorry $sh_var shell is not matched"
esac
;;
3) read -p "Enter a port number:" port
if [ $port -gt 1000 -a $port -lt 2000 ]
then
echo "Running app port number is:$port"
else
default_port=8000
echo "default port:$default_port is initialized"
fi
;;
4) echo -e "Working kernel `uname -rs`\t hostname:`hostname`\nLogin
name:`whoami`\t Today:`date +%D`"
;;
5) echo "Thank you"
exit # exit from script
;;
*) echo "Invalid Choice"
esac
===================================================================================
==========================
root@host~]# uname;ps;date;pwd;df -Th;ls
| | | | |

; - end of the command (or) end of the statement

if [ condition ]
then if [ condition ];then
... ....
else => else
... ....
fi fi

===================================================================================
==========================
Looping statements
-------------------
|->Code block - execute more than one time.
...................
conditional statement Vs looping statement

- block will execute block will execute more than one


only one time. time

- if,case while,for,until,select

------------------------------------------------------------------------
- in shell script looping statements

1. conditional style loop - while until


2. collection style loop - for select

1. conditional style loop


----------------------------
-> Code block execute more than one time
|
-> execute - based on the condition
---------
like if statement - test,relational,logical operators

Rule 1: initialization 0 15
|
Rule 2: test the condition 5 -> 0 to 5 15 ... 0
|
Rule 3: arithmetic increment(add-expr) decrement(sub-expr)

Syntax:-
---------
initialization
while [ condition ]
do
code block
arithmetic operation
done

i=0
while [ $i -lt 5 ]
do
uptime;sleep 2
i=`expr $i + 1` # ((i++))
done

-------------------------------------------------------------------------

Write a shell script:

step 1: read a login name from <STDIN>


|
step 2: test input login name is userA or not
| |->not matched
matched

Give maximum limit is 3 choice


------------------------ //while loop
i=0
while [ $i -lt 3 ]
do
read -p "Enter a login name:" name

if [ $name == "userA" ];then


echo "Matched"
else
echo "Not-matched"
fi

i=`expr $i + 1`
done

break - exit from loop


-----

-------------------------------------------------------------------------------
while<space>:
do
code block <== always active
done

(or)
while true
do
Code block
done

-----------------------------------------------------
until
------
-> opp.while loop
|
-> until loop - test the condition ->True ->won't execute the code block
|
|----->False -> execute the code block
until [ condition ]
do
code block
..
done

|
same as
|
while ! [ condition ]
do
....
done

while [ $used -gt 1000 ] -> until [ $used -lt 1000 ]


do do
.... ...
done done

-----------------------------------------------------------------------------------

Collection style - for select


----------------- ==========

Syntax:-
----------
for variable in <collection of items>
do
code block
done

# for in do done - keywords

for v in 10 1.45 data /etc/passwd 127.0.0.1 <== each item separated by space
do
echo "v value is:$v" <== code block
done

v value is:10
v value is:1.45
v value is:data
v value is:/etc/passwd
v value is:127.0.0.1

for v in data1 data2 data3


do
echo "Hello...$v"
done

Hello...data1
Hello...data2
Hello...data3

break - exit from loop


|
continue - ignore current iteration - continue next item (won't exit from loop)
=========
|->looping keywords

-> we can't use break,continue keywords outside the loops


-------------------------------------------------------------------------------

Q1. Write a shell script

step 1: initialize a pin number( ex: pin=1932)


|
step 2: using while loop (max limit is 3)
|
|-> read a pin number from <STDIN>
|-> test with your input pin and initialized pin(step -1)
-------------------------------------
|->matched - display message - pin is matched

step 3: if all 3 inputs are failed - display message - pin is blocked.

Expected result
----------------
Enter a pin number:1932
Success pin is matched - at 1
Enter a pin number:3433
Enter a pin number:1932
Success pin is matched - at 2

Enter a pin number:3433


Enter a pin number:4334
Enter a pin number:1932
Success pin is matched - at 3

Enter a pin number:3434


Enter a pin number:5233
Enter a pin number:3233
pin is blocked.

_______________________________________________________________________________
Q2. Write a shell script

step 1: read a file name from <STDIN>


|
test input file is exists or not
|
message - file is already exists
different file name - exit from script

step 2: using while loop - 10times


|
|->execute few commands
|->redirect command result to external file(step 1)

command >newfile
--------
|
create/write

command >>newfile
--
|->append operation - won't overwrite existing file

c=0
while [ $c -lt 5 ]
do
uptime
c=`expr $c + 1`
done >result.log
|------------
---------------------------------------------------------------------------
Q3. Write a shell script
|
step 1: create two directories (mkdir reg_file dirs)
|
step 2: using for loop - iterate list of files

- test input file is regular file -> copy reg.file to reg_files


- test input file is directory file ->copy dir.file to dirs
|
step 3: using tar command - create backup of two dirs
tar -cf B1.tar reg_files
tar -cf B2.tar dirs
|
if tar operation is failed - display message to user.
--------------------------------------------------------------------------------

tar
---
-> create a tar file -> cf =>cvf
-> list a tar file -> tf =>tvf
-> extract a tar file -> xf =>xvf

create a tar file


------------------
tar -cf <backupfile.tar> <list of inputfiles>

ex:-
------
root@krosumlabs:~/ShellScript_Training# tar -cvf B1.tar *.sh Demo/ Dx/ Dy/ chat
p10.sh
p11.sh
p12.sh
p13.sh
p14.sh
p15.sh
p16.sh
p17.sh
p18.sh

root@krosumlabs:~/ShellScript_Training# tar -cf B2.tar *.sh Demo/ Dx/ Dy/ chat


root@krosumlabs:~/ShellScript_Training#
root@krosumlabs:~/ShellScript_Training# ls -t
B2.tar p38.sh p33.sh p28.sh chat p21.sh p16.sh p12.sh p7.sh p2.sh
B1.tar p37.sh p32.sh Dy p25.sh p20.sh Dx p11.sh p6.sh p1.sh
p41.sh p36.sh p31.sh Demo p24.sh p19.sh p15.sh p10.sh p5.sh

root@krosumlabs:~/ShellScript_Training/Demo# tar -tvf B1.tar


-rwxr-xr-x root/root 454 2022-08-08 14:26 p10.sh
-rwxr-xr-x root/root 76 2022-08-08 14:32 p11.sh
-rwxr-xr-x root/root 124 2022-08-08 14:49 p12.sh
-rwxr-xr-x root/root 415 2022-08-08 15:20 p13.sh
-rwxr-xr-x root/root 436 2022-08-08 15:29 p14.sh
-rwxr-xr-x root/root 574 2022-08-08 15:38 p15.sh
-rwxr-xr-x root/root 149 2022-08-08 16:03 p16.sh
-rwxr-xr-x root/root 172 2022-08-08 16:04 p17.sh
-rwxr-xr-x root/root 117 2022-08-08 16:34 p18.sh
-rwxr-xr-x root/root 213 2022-08-08 16:38 p19.sh
-rwxr-xr-x root/root 254 2022-08-08 11:45 p1.sh

root@krosumlabs:~/ShellScript_Training/Demo# tar -xvf B1.tar


p10.sh
p11.sh
p12.sh
p13.sh
p14.sh
p15.sh
p16.sh
p17.sh
p18.sh
p19.sh
..
-----------------------------------------------------------------------------------
-
Calculate sum of size

size="120 450 60 30 10"


----
|
use for loop

--------------------------------------------------------------------------------
select loop
-----------
|-> Collection style loop
|-> menu driven
|-> always active
|-> #? prompt
|-> syntax like for loop style

Syntax:-
--------
select variable in <list of menu items>
do
code block
done

select + case
------ =====
| |->conditional code
loop

select variable in menu1 menu2 menu3 quit


do
case $variable in
menu1) menu1 operation ;;
menu2) menu2 operation ;;
menu3) menu3 operation ;;
quit) break ;;
*) invalid choice
esac
done

-----------------------------------------------------------------
prompt => primary prompt => username@hostname <workingdir>]#

root@host~]# userA@host~]$ userB@host~]$

PS1 - primary prompt

secondary prompt
------------------
root@host~]# echo "one
>two
>three
>four
>five"
|
secondary prompt

PS2

echo $PS2 -> >

select loop prompt is #? <== PS3

debugging prompt is + <== PS4


---------------------------------------------------------------------------------
echo "

******** Select your package *********


* *
* 1. gcc *
* 2. shell name *
* 3. App *
* 4. system info *
* 5. Quit *
* *
************************************** "

read -p "Enter your choice:" choice


case $choice in
1) read -p "Enter your gcc version:" gv
if [ $gv -ge 4 -a $gv -le 6 ]
then
echo "selected gcc version is $gv"
else
echo "Select 4-6 version"
fi
;;
2) read -p "Enter a shell name:" sh_var
case $sh_var in
sh|ksh|bash) echo "selected shell name is:$sh_var" ;;
*) echo "Sorry $sh_var shell is not matched"
esac
;;
3) read -p "Enter a port number:" port
if [ $port -gt 1000 -a $port -lt 2000 ]
then
echo "Running app port number is:$port"
else
default_port=8000
echo "default port:$default_port is initialized"
fi
;;
4) echo -e "Working kernel `uname -rs`\t hostname:`hostname`\nLogin
name:`whoami`\t Today:`date +%D`"
;;
5) echo "Thank you"
exit # exit from script
;;
*) echo "Invalid Choice"
esac

----------
while :
do
echo "

******** Select your package *********


* *
* 1. gcc *
* 2. shell name *
* 3. App * -> select variable in menulist
* 4. system info * do
* 5. Quit * case $variable
* * ...) ... ;;
************************************** " *) ...
esac
read -p "Enter your choice:" choice done
case $choice in
1) read -p "Enter your gcc version:" gv
if [ $gv -ge 4 -a $gv -le 6 ]
then
echo "selected gcc version is $gv"
else
echo "Select 4-6 version"
fi
;;
2) read -p "Enter a shell name:" sh_var
case $sh_var in
sh|ksh|bash) echo "selected shell name is:$sh_var" ;;
*) echo "Sorry $sh_var shell is not matched"
esac
;;
3) read -p "Enter a port number:" port
if [ $port -gt 1000 -a $port -lt 2000 ]
then
echo "Running app port number is:$port"
else
default_port=8000
echo "default port:$default_port is initialized"
fi
;;
4) echo -e "Working kernel `uname -rs`\t hostname:`hostname`\nLogin
name:`whoami`\t Today:`date +%D`"
;;
5) echo "Thank you"
exit # exit from script
;;
*) echo "Invalid Choice"
esac

done

========================================================================
|
modify the above code - use select loop - demonstrate menu driven programming

===================================================================================
=
mkdir Temp
cd Temp
| |

file: f1.sh file: f2.sh


-------------- -------------
while: use for loop - iterate list of .log files
do ignore following file R1.log R2.log R5.log R7.log
.. display remaining file details(use ls -l <filename>)
done
r1.log
|
r2.log
|
r3.log
|
r4.log

count=0
..

>"r$count".log
------

c=0
while [ $c -lt 5 ]
do
uptime;sleep 3
date;sleep 2
ps;sleep 1
c=`expr $c + 1`
done >r1.txt

command >resultfile
-------
|
execute
|
then - write to file

Vs

c=0
while [ $c -lt 5 ]
do
uptime >>LB.log ; sleep 3
date >D1.log ; sleep 2
ps >>p1.log ; sleep 1
c=`expr $c + 1`
done
|
after finished loop execution
open LB.log file - will get 5entries of uptime result
--
open D1.log file - will get only one entry of date command result
----------------
==================================================================================
Commandline arguments
______________________
->Runtime inputs
|
->non-interactive inputs
|
->in shell script commandline arguments are called positional parameters

$1 ->1st argument in commandline


$2 ->2nd argument in commandline
..
$9 ->9th argument in commandline

$@ ->list of all the args


$* ->list of all the args

$# ->total no.of arguments

--------------
file: p1.sh
-------------
read -p "Enter a IP Address:" IP <== interactive input(or) execution input
read -p "Enter a count value:" count <== interactive input(or) execution input

ping -c $count $IP >/var/log/ping_test.log

-------------------------------------------
root@host~]# ./p1.sh {Enter}
Enter a IP Address:

|
cronjob
-------
|->crond daemon

crontab -e {enter}
30 22 * * * /root/p1.sh
=============

crond ->bash ->/root/p1.sh

/root/p1.sh {Enter}
Enter a IP Address:

--------------------------------------------------------------------
file: p2.sh
--------------
echo $1 $2 $3
---------------
root@host~]# chmod a+x p2.sh
root@host~]# ./p2.sh <input1> <input2> <input3> {Enter}
__________________________
|<= commandline args inputs

root@host~]# ./p2.sh 10 2.45 data {Enter}


10 2.45 data

root@host~]# ./p2.sh /etc/passwd 10.20.30.45 `uname` {Enter}


-----$1---- -----$2---- --$3--
/etc/passwd 10.20.30.40 Linux

--------------
file: p1.sh
-------------
read -p "Enter a IP Address:" IP <== interactive input(or) execution input
read -p "Enter a count value:" count <== interactive input(or) execution input

ping -c $count $IP >/var/log/ping_test.log

-------------------------------------------
root@host~]# ./p1.sh {Enter} <==
Enter a IP Address: 127.0.0.1<== execution input

Vs

file: p3.sh
------------------------------------------
ping -c $1 $2 >/var/log/ping_test.log
-----------------------------------------
root@host~]# chmod a+x p3.sh

root@host~]# ./p3.sh 3 127.0.0.1 {Enter} <==


- ---------
| |
-----
|<- runtime input

30 22 * * * /root/p3.sh 3 127.0.0.1
-----------
________________________________________________________________________________

$# - total no.of commandline args

if [ $# -eq 0 ];then
echo "Usage: Commandline args is empty"
fi

if [ $# -gt 3 ];then
echo "Usage: Given argument is more than 3"
fi

-> using commandline args - calculate sum of two numbers

expr $1 + $2
-- --

-> using commandline args - test inputfile is exists or not

[ -e <filename> ]
|
getting from <commandline>
$1 <== 1st argument
./p1.sh <inputfile>{Enter}
___________

if [ -e $1 ]
then
echo "file:$1 is exists"
else
echo "file:$1 is not exists"
fi
----------------------------------------------------------
Old version - shift command
-----
|->shift the positional parameters

shift <number>
--------

echo $1 $2 $3 $8 $9
-- -- -- -- ---
1st 2nd 3rd 8thposition 9thposition

shift 2

echo $1 $2 $3 $8 $9
-- -- -- -- ---
| | | | |->11th argument
| | | 10th argument
| | 5th argument
| 4th argument
3rd argument

------------------------------------------------------------------------------
Updated version -> ${n} - nth argument

echo $1 $2 $5 $9 --same as -> echo ${1} ${2} ${5} ${9}

echo ${10} ${11} ${15}


| | |
10th 11th 15th arg

echo $@ => ${@}


echo $* => ${*}
echo $# => ${#}
-------------------------------------------------------------------------------
in shell commandline => $0 <== working shell name
$$ <== working shell PID
___
inside shellscript(file.sh) - $0 <== running script filename
$$ <== running script process ID(PID)

$1 $2 $3... $9
(or)
${1} ${2} ${3} ... ${9} ${10} ${11} ... ${n}

$# - total no.of args <= ${#} (or) $#


$@ - list of args <== ${@} (or) $@

$* - list of args <== ${*} (or) $*

mkdir $1

file: pt.sh
----------------
for v in $@
do
touch $v
done
------------------
./pt.sh test1 test2 test3 test4 {enter}
ls
test1 test2 test3 test4

-----------------------------------------------------------------------------------
-------------------

You might also like