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