08 Linux Scripting
Ambjenti i zhvillimit
Skriptet mund ti krijoni me editorin e tesktit qe preferoni. Me pas duhet ti jepni te dretja ekzekutimi skedarit Tuaj.
Pas kesaj eshte e mundur qe te therrisni skriptin.
Per shembull po krijojme nje skript me emrin hello.world ne dosjen tone /home
[root@localhost student]# cat ./hello.world
#!/bin/bash
echo "hello world"
Do ti lejojme te drejta ekzektutimi per te gjithe mbi skedarin tone:
[root@localhost student]# chmod a+x ./hello.world
[root@localhost student]# ls -l hello.world
-rwxr-xr-x. 1 root root 31 Apr 1 01:26 hello.world
[root@localhost student]#
Tani mund ta therrasim skriptin tone te pare:
[root@localhost student]# ./hello.world
hello world
[root@localhost student]#
Simbolet e vecanta
Variablat
Variablat nuk eshte e nevojshme qe te deklarohen paraprakisht. Variablat kane tipe dinamike. Ato i marrin tipet mbi bazen e vleres qe kane.
Per te krijuar nje variabel mjafton qe ti japim vlere atij.
Nese duam ti referohemi vleres se tij do te perdorim si prefix shenjen e $.
Emri i variablit nuk paraprihet nga shenja $ ne momentin e krijimit te tij ose ne instruksione vleredhenie, ku i jepet vlere atij variabli.
Per shembull:
[root@localhost student]# cat hello.world
#!/bin/bash
mesazh="Pershendetje nga skripti"
echo $mesazh
nese do ta therrasim skriptin:
[root@localhost student]# ./hello.world
Pershendetje nga skripti
[root@localhost student]#
Zevendesimi i variablave ( variable substitution )
Emri i variablit eshte nje shenjues ne bytine e pare te zones se memorjes ku ruhet vlera e variablit.
Kapja e vleres se variablit quhet zevendesim i variablit ose "variable substitution"
Emrat e variablave paraprihen nga shenja e dollarit $ , sa here qe ata referohen, me perjashtim te rastit te vleredhenies dhe te "export" me $((myvar+1 )) ne nje shprehje aritmetike.
[student@localhost ~]$ myvar=1
[student@localhost ~]$ echo $myvar
1
[student@localhost ~]$
Vleredhenia
Nje variabel mund te marre vlere :
nepermjet nje isntruksioni vleredhenie myvar=1
nepermjet funksionit read
nepermjet nje cikli psh for myvar in 1 2 3
Ne rastin e nje instruktioni vleredhenie nuk lejohet hapesira:
midis emrit te variablit dhe operatorit te vleredhenies =
operatorit te vleredhenies = dhe vleres se variablit
Kodi :
[student@localhost ~]$ myvar =1
bash: myvar: command not found
gjeneron gabim, po keshtu edhe kodi
[student@localhost ~]$ myvar= 1
bash: 1: command not found
gjeneron gabim, ndersa kodi eshte i sakte pasi nuk ka hapesire as perpara dhe as pas shenjes se barazimit.
[student@localhost ~]$ myvar=1
[student@localhost ~]$
Operatori let
Variablat mund ti jepet vlere gjithashtu duke perdorur operatorin let. Shembulli me poshte ilustron sintaksen:
[student@localhost ~]$ let myvar=20
Thonjezat mbrapsht ` `
Thonjezat mbrapsht mund te perdoren per te kthyer vleren e nje komande,
per shembull
[student@localhost ~]$ echo `echo "hello world" `
hello world
[student@localhost ~]$
Zevendesimi i komandave me $( komande)
Nje menyre me e mire per efekt te lexueshmerise se kodit do te ishte $( komande )
[student@localhost ~]$ echo $(echo "hello world")
hello world
[student@localhost ~]$
ose
[student@localhost ~]$ echo $(ls /home)
krista krista2 level1 lost+found student
[student@localhost ~]$
Tipet e variblave ( tekst apo numer)
Variablat i marrin tipet ne menyre dinamike ne varesi te vleres se tyre.
Ne varesi te tipit te variablit trajtohen edhe veprimet aritmetike. Kujtojme qe + eshte veprimi aritmetik i mbledhjes por ne te njejten kohe eshte dhe operatori i konkatenimit te stringjeve.
Vini re shembullin me poshte
[student@localhost ~]$ echo $a
student
[student@localhost ~]$ a+=1
[student@localhost ~]$ echo $a
student1
[student@localhost ~]$
Nese variablit a qe ka vlere tekst i shtojme 1 veme re qe rezultati eshte nje "1" i shtuar ne fund te fjales.
Ndersa nese duam qe te zevendesojme variablat ne nje shprehje aritmetike atehere do te perdorim dy here kllapat e rrumbullaketa:
[student@localhost ~]$ echo a=$a,b=$b
a=student,b=1
[student@localhost ~]$ echo $((a+b))
1
[student@localhost ~]$ a=3
[student@localhost ~]$ echo $((a+b))
4
[student@localhost ~]$
unset
Per te fshire nje variabel perdorim funksionin unset, si me poshte:
[student@localhost ~]$ echo $myvar
[student@localhost ~]$ myvar=10
[student@localhost ~]$ echo $myvar
10
[student@localhost ~]$ unset myvar
[student@localhost ~]$ echo $myvar
[student@localhost ~]$
weak quoting vs strong quoting
Vendosja e references se nje variabli ( me $) midis thonjezave ka efekte te ndryshme midis thonjezave dyshe (qe quhet "weak quoting") dhe tonjezave teke ( qe quhet " strong quoting".
Kodi me poshte ilustron dallimin midis weak dhe strong quoting:
[student@localhost ~]$ echo "$myvar"
1
[student@localhost ~]$ echo '$myvar'
$myvar
[student@localhost ~]$
Strukturat e kontrollit
if then else
Sintaksa e pergjithshme e instruksionit if then else eshte:
Shenim pikepresja eshte vendosur pasi shprehja e ndare me hapesire nga kllapat eshte vendosur ne nje rresht me then
if [ shprehje ] ; then
instruktione
else
instruksione
fi
ose pa vendosur pikepresje por ne kete rast duhet te kalojme then ne rreshtin pasardhes
if [ shprehje ]
then
instruktione
else
instruksione
fi
Ushtrim
Ekzekutoni tre skriptet e meposhtme dhe sqaroni ne cdo rast ne se ka gabim cili eshte gabimi:
Cikli for
Cikli for ka nje implementim te ndryshem nga gjuha C. Cikli for sherben per te iteruar ne nje liste me vlera per shembull:
#!/bin/bash
mesazh="Pershendetje nga skripti"
echo $mesazh
for i in $(ls); do
echo $i
done
Skripti do te afishonte permbajtjen e dosjes korrente
[root@localhost student]# ./hello.world
Pershendetje nga skripti
Desktop
Documents
Downloads
hello.bsh
hello.world
Music
Pictures
Public
slaes
Templates
Videos
[root@localhost student]#
Lista e vlerave ne te cilen merr vlere variabli mund te jete fikse , mund te jete interval ose rezultati i nje komande si ne rastin e pare ( lista perbehej nga vlerat qe kthene komanda ls)
Shembujt me poshte ilustrojne perdorimin e ciklit for per te iteruar ne nje sekuence numrash
for i in {1..5}; do
echo $i
done
do te afishonte:
[root@localhost student]# ./hello.world
1
2
3
4
5
[root@localhost student]#
ndersa
#!/bin/bash
for i in {5..1}; do
echo $i
done
do te afishonte
[root@localhost student]# ./hello.world
5
4
3
2
1
[root@localhost student]#
Ndersa
#!/bin/bash
for i in 2 4 6; do
echo $i
done
do te afishonte numrat nga 2 deri tek 6
[root@localhost student]# ./hello.world
2
4
6
[root@localhost student]#
Cikli while
Cikli while merr si argument nje kusht llogjik dhe iteron per sa kohe kushti eshte i vertete
Shembulli me poshte ilustron kete perdorim:
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=$COUNTER+1
done
Cikli until
Cikli until eshte i kunderti i ciklit while. Ehe until merr si argument nje kusht llogjik por iteron per sa kohe kushti nuk eshte i vertete.
#!/bin/bash
COUNTER=6
until [ $COUNTER -lt 1 ]; do
echo The counter is $COUNTER
let COUNTER=$COUNTER-1
done
Shembulli me lart do te afishonte numrat nga 6 tek 1
[root@localhost student]# ./hello.world
The counter is 6
The counter is 5
The counter is 4
The counter is 3
The counter is 2
The counter is 1
[root@localhost student]#
Operatoret e krahasimit
Per te shmagur gabimet qe mund te shkaktohen nga perdorim i simboleve te krahasimit <,> qe jane gjithashtu edhe operatoret e ridrejtimit ekzistojne operatoret te tjere krahasimi qe mund te perdoren per te formuar shprehjet llogjike.
integer comparison
-eq
is equal to
if [ "$a" -eq "$b" ]
-ne
is not equal to
if [ "$a" -ne "$b" ]
-gt
is greater than
if [ "$a" -gt "$b" ]
-ge
is greater than or equal to
if [ "$a" -ge "$b" ]
-lt
is less than
if [ "$a" -lt "$b" ]
-le
is less than or equal to
if [ "$a" -le "$b" ]
<
is less than (within double parentheses)
(("$a" < "$b"))
<=
is less than or equal to (within double parentheses)
(("$a" <= "$b"))
>
is greater than (within double parentheses)
(("$a" > "$b"))
>=
is greater than or equal to (within double parentheses)
(("$a" >= "$b"))
Operatoret mbi stringjet
=
is equal to
if [ "$a" = "$b" ]
Shenim
kujdes hapesirat
!=
is not equal to
if [ "$a" != "$b"
Shenim
Ky operator se bashku me == qe eshte sinonim i = mund te realizojne patern matching ( kerkime me karaktere te vecanta psh z*) nese vendosen midis dy kllapave katrore
-Z
stringu eshte null, me gjatesi 0 karaktere
if [ -z "$1" ]; then
echo usage: $0 directory
exit
Funksionet
Krijimi i funksioneve dhe therritja e tyre
(shembulli)
#!/bin/bash
function sayhello()
{
msg=$1
echo $msg
}
COUNTER=6
until [ $COUNTER -lt 1 ]; do
sayhello " The counter is $COUNTER"
let COUNTER=$COUNTER-1
done
Nderfaqa me perdoruesin
Komanda select
Qendron brenda komandes derisa te therritet exit
#!/bin/bash
menu="Hello Quit"
select opt in $menu; do
if [ "$opt" = "Quit" ]; then
echo done
exit
elif [ "$opt" = "Hello" ]; then
echo Hello World
else
clear
echo bad option
echo "1) Hello"
echo "2) Quit"
fi
done
Kapja e argumentave ne therritje te skriptit
#!/bin/bash
if [ -z "$1" ]; then
echo usage: $0 directory
exit
else
arg=$1
echo "you entered" $arg
fi
Leximi i input te perdoruesit me funksionin read
#!/bin/bash
echo " Shkruani emrin tuaj"
read emri
echo " shkruani mbiemrin tuaj"
read mbiemri
echo "Mire se erdhet $emri $mbiemri"
Veprimet aritmetike
Nje shprehje aritmetike fillon me shenjen e dollarit dhe vendos ne kllapa te rrumbullaketa te dyfishta:
#!/bin/bash
echo " Shkruani numrin e pare"
read nr1
echo " shkruani numrin e dyte "
read nr2
sh=$(($nr1+$nr2))
echo "shuma e $nr1 me $nr2 eshte= $sh"
Date & Time
Variabli date kthen kohen e momentit Duke perdorur nje maske mund te formatohet data sipas formatit te deshiruar.
Shpesh per te gjeneruar emra unke skedarish si ne rastin e backup i bashkengjitete koha e backup skedarit si nje prapashtese.
Sintaktsa per te formatiar daten eshte
date +format
shikoni shembullin me poshte:
[root@localhost student]# date +%m-%d-%Y%k:%M:%S
04-01-2014 4:29:48
Tabela me poshte liston flaget e mundshme te formatimit te dates:
Shkrimi ne skedare me emra te bazuar ne kohen e ekzekutimit
Shembull
#!/bin/bash
file="sample.txt."$(date +%d-%m-%Y_%k:%M:%S)
#touch $file
#echo $file
echo "hello" > "$file"
Llogatitja e kohezgjatjes se nje veprimi
#!/bin/bash
start=$(date +%s)
echo "Start on $start"
for i in {1..1000000}
{
d=100
}
end=$(date +%s)
echo "Ended on $end"
diff=$(($end-$start))
echo "duration: $diff"
Shtimi ose heqja e njesive nga nje date
Shembuj
[root@localhost student]# date -d 'now'
Tue Apr 1 05:08:47 PDT 2014
[root@localhost student]# date -d 'now + 3 weeks'
Tue Apr 22 05:08:56 PDT 2014
[root@localhost student]# date -d 'now + 3 days'
Fri Apr 4 05:09:08 PDT 2014
[root@localhost student]# date -d 'now + 3 months'
Tue Jul 1 05:09:13 PDT 2014
[root@localhost student]# date -d 'now + 3 years'
Sat Apr 1 05:09:21 PDT 2017
[root@localhost student]# date -d 'now - 3 years'
Fri Apr 1 05:09:38 PDT 2011
Ushtrime
1- Leximi i skedarit emri i te cilit eshte argument i skriptit
Ndertoni nje skript qe merr si argument nje skedar dhe afishon permbajtjen e tij. Nese skripti nuk e merr skedarin si argumetn duhet te njoftoje perdoruesin per menyren si duhet ta therrase skriptin
Zgjidhje
skript1.sh
if [ -z "$1" ]
then
echo usage: $0 file to read
exit
fi
while read line
do
echo $line
done < "$1"
2- Komunikimi me perdoruesin ne skript
Ndertoni nje skript qe i kerkon perdoruesit te fuse dy numra. Skripti do te gjeje dhe afishoje shumen e ketyre dy numrave
calculator.sh
#1/bin/bash
echo "Futni numrin e pare"
read nr1
echo "Futni numrin e dyte"
read nr2
shuma = $( "$nr1" + "$nr2" )
echo "shuma eshte= $shuma"
3- Funksionet me kohen
Modifikoni skriptin calculator ne menyre te tille qe ne perfundim te shfaqe sa sekonda qendroi skripti ne ekzekutim:
calculator2.sh
#1/bin/bash
clear
start=$(date +%s)
s2=$(date +%m-%d-%Y%k:%M:%S)
echo "Skripti filloi ekzekutimin ne $s2"
echo " e konvertuar ne sekonda " $start
echo "****************************************"
echo "Futni numrin e pare"
read nr1
echo "Futni numrin e dyte"
read nr2
shuma=$((nr1 + nr2))
echo "shuma eshte= $shuma"
end=$(date +%s)
e2=$(date +%m-%d-%Y%k:%M:%S)
echo "****************************************"
echo "Skripti e perfundo ekzekutimin ne $e2"
koha=$(($end-$start))
echo "Skripti u ekzekutua per $koha sekonda"
4- Leximi i skedarit
Ndertoni nje skript qe merr si argument nje skedar dhe afishon permbajtjen e tij. Nese skripti nuk e merr skedarin si argument atehere duet te pyese perdoruesin per emrin e skedarit. Pasi te lexoje emrin e ksedarit nga perdoruesi duhet te afishoje ate rresht per rresht. Skripti duhet te ndertoje nje funksion i cili lexon skedarin dhe e afishon rresht per rresht dhe ta therrase ate funksion. Funksioni do ta marre emrin e skedarit si argument.
zgjidhje
clear
if [ -z "$1" ]
then
echo Give the name of the file to read
read fname
else
fname="$1"
fi
readfile $fname
function readfile()
{
while read line
do
echo $line
done < "$1"
}
Nese do ta therrisnim skriptin me lart do te merrnim nje mesazh gabimi si me poshte:
Give the name of the file to read
test
./filerw3: line 14: readfile: command not found
[student@localhost ~]$
Cila eshte arsyeja?
Pse versioni i meposhtem i skriptit nuk jep gabim?
function readfile()
{
while read line
do
echo $line
done < "$1"
}
clear
if [ -z "$1" ]
then
echo Give the name of the file to read
read fname
else
fname="$1"
fi
readfile $fname
5- Numerimi i rreshtave te skedarit
Modifikoni skriptin e pikes 4 ne menyre te tille qe te gjeje dhe te afishoje numrin e rreshtave qe ka funksioni
zgjidhje
function readfile()
{
while read line
do
echo $line
done < "$1"
}
function count()
{
counter=0
while read line
do
let counter=$counter+1
echo $counter $line
done < "$1"
return $counter
}
clear
if [ -z "$1" ]
then
echo Give the name of the file to read
read fname
else
fname="$1"
fi
readfile $fname
count $fname
ret=$?
echo $ret
5- Shuma e numrave qe gjenen ne rreshtat e nje skedarit
Modifikoni skriptin e pikes 4 ne menyre te tille qe duke supozuar qe skedari qe merr si argument permban nje liste me numra ( nje numer ne nje rresht) gjen dhe afishon shumen e atyre numrave
function readfile()
{
while read line
do
echo $line
done < "$1"
}
function count()
{
counter=0
while read line
do
let counter=$counter+1
echo $counter $line
done < "$1"
return $counter
}
function sum()
{
s=0
while read line
do
s=$(($s+$line))
echo $s $line
done < "$1"
return $s
}
clear
if [ -z "$1" ]
then
echo Give the name of the file to read
read fname
else
fname="$1"
fi
readfile $fname
count $fname
ret=$?
# vlera qe kthen funksioni menjehere me lart
echo File $fname has $ret rows
sum $fname
ret=$?
echo sum of numbers in $fname is $ret