Tazi statiia e prevedena s razreshenieto na avtora i X_console.
Adresut na originalnata statiia e http://xfactor.itec.yorku.ca/~xconsole/.
Produlzhenie na [ chast 1 ].
Uslovni operatori
Uslovnite operatori vi pozvoliavat vashata
programa da "vzema resheniia" i ia praviat
po-kompaktna. Koeto e po-vazhno s tiah mozhe da
proveriavate za greshki. Vsichki primeri do sega
zapochvaha izpulnenieto si ot purviia red do
posledniia bez nikakvi proverki. Za primer:
#!/bin/bash
cp /etc/foo .
echo "Done."
Tazi malka shel programa kopira failut /etc/foo
v tekushtata direktoriia i izpechatva "Done" na
ekrana. Tazi programa shte raboti samo pri edno
uslovie. Triabva da ima fail /etc/foo
.
V protiven sluchai shte se poluchi sledniia rezultat:
xconsole$ ./bar.sh
cp: /etc/foo: No such file or directory
Done.
Kakto vizhdate imame problem. Ne vseki koito
startira vashata programa ima fail /etc/foo
na
sistemata si. SHTe bude po-dobre, ako vashata
programa proveriava dali faila /etc/foo
sushtestvuva i ako tova e taka da produlzhi s
kopiraneto, v protiven sluchai da spre
izpulnenieto. S "psevdo" kod tova izglezhda
taka:
if /etc/code exists, then
copy /etc/code to the current directory
print "Done." to the screen.
otherwise,
print "This file does not exist." to the screen
exit
Mozhe li tova da bude napraveno s bash
?
Razbira se! V bash
uslovnite operatori sa: if
,
while
, until
, for
, i case
.
Vseki operator zapochva s klyuchova duma i zavurshva
s klyuchova duma. Naprimer if
operatora
zapochva s klyuchovata duma if
, i zavurshva s fi
.
Uslovnite operatori ne sa programi vuv vashata
sistema. Te sa vgradeni svoistva na bash
.
if ... else ... elif ... fi
E edin ot nai-chesto izpolzvanite uslovni
operatori. Toi dava vuzmozhnost na programa da
vzeme resheniia ot roda na "napravi tova ako(if)
tova uslovie e izpulneno, ili(else)
pravi neshto drugo". Za da izpolzvate efektivno
uslovniia operator if triabva da
izpolzvate komandata test
. test
proveriava za sushtestvuvane na fail, prava,
podobiia ili razliki. Eto programata bar.sh
:
#!/bin/bash
if test -f /etc/foo
then
# file exists, so copy and print a message.
cp /etc/foo .
echo "Done."
else
# file does NOT exist, so we print a message and exit.
echo "This file does not exist."
exit
fi
Zabelezhete che redovete sled then
i else
sa malko po-navutre. Tova ne e zadulzhitelno, no se
pravi s tsel programata da bude po-lesna za chetene. Sega startiraite programata. Ako
imate fail /etc/foo
, togava programata shte go
kopira v tekushtata direktoriia, v protiven sluchai
shte vurne suobshtenie za greshka. Optsiiata -f
proveriava dali tova e obiknoven fail. Eto spisuk
s optsiite na komandata test
:
-d proveriava dali failut e direktoriia
-e proveriava dali failut sushtestvuva
-f proveriava dali failut e obiknoven fail
-g proveriava dali failut ima SGID prava
-r proveriava dali failut mozhe da se chete
-s proveriava dali failut raznerut na faila ne e 0
-u proveriava dali failut ima SUID prava
-w proveriava dali vurhu failut mozhe da se pishe
-x proveriava dali failut e izpulnim
else
se izpolzva ako iskate vashata
programa da napravi neshto drugo, ako purvoto
uslovie ne e izpulneno. Ima i klyuchova duma elif
,
koiato mozhe da bude izpolzvana vmesto da pishete
drug if
vutre v purviia if
. elif
idva ot angliiskoto "else if". Izpolzva se
kogato purvoto uslovie ne e izpulneno i iskate da
proverite za drugo uslovie.
Ako ne se chuvstvate komfortno s if
i test
sintaksisa, koito e :
if test -f /etc/foo
then
togava mozhe da izpolzvate sledniia variant:
if [ -f /etc/foo ]; then
Kvadratnite skobi formirat test
komandata. Ako imate opit v programiraneto na C
tozi sintaks mozhe da vi se stori po-udoben.
Zabelezhete, che triabva da ima razstoianie sled
otvariashtata kvadratna skoba i predi zatvariashtata.
Tochkata i zapetaiata: ";
" kazva na shela
che tova e kraia na komandata. Vsichko sled ";"
shte bude izpulneno siakash se namira na sledvashtiia
red. Tova pravi programata malko po-chetima.
Mozhete razbira se da slozhite then
na
sledvashtiia red.
Kogato izpolzvame promenlivi s test
e
dobre da gi zagradim s kavichki. Naprimer:
if [ "$name" -eq 5 ]; then
while ... do ... done
while
operatora e usloven operator za tsikul.
Nai-obshto kazano, tova koeto pravi e
"while(dokato) tova uslovie e viarno, do(izpulni)
komandite done ". Neka da vidim sledniia primer:
#!/bin/bash
while true; do
echo "Press CTRL-C to quit."
done
true
v deistvitelnost e programa. Tova
koeto pravi tazi programa e da se izpulniava
bezkraino. Izpolzvaneto na true
se smiata,
che zabavia vashata programa, zashtoto shel
interpretatora purvo triabva da izvika
programata i sled tova da ia izpulni. Vmesto tova
mozhe da izpolzvate komandata ":
":
#!/bin/bash
while :; do
echo "Press CTRL-C to quit."
done
Po tozi nachin vie postigate sushtiia rezultat, no
dosta po burzo. Edinstveniia nedostatuk e, che
programata stava po-trudno chetima. Eto edin
po-podroben primer, koito izpolzva promenlivi:
#!/bin/bash
x=0; # initialize x to 0
while [ "$x" -le 10 ]; do
echo "Current value of x: $x"
# increment the value of x:
x=$(expr $x + 1)
sleep 1
done
Kakto vizhdate izpolzvame test
(zapisana kato kvadratni skobi) za da proverim
sustoianieto na promenlivata x
.
Optsiiata -le
proveriava dali x
e
po-malko(less) ili ravno(equal) na 10.
Na govorim ezik tova se prevezhda po sledniia nachin
"Dokato(while) x e po-malko ili ravno na 10, pokazhi
tekushtata stoinost na x, i sled tova dobavi 1 kum
tekushtata stoinost na x.". sleep 1
kazva na programata da spre izpulnenieto si za
edna sekunda. Kakto vizhdate tova koeto pravim tuk
v da proverim za ravenstvo. Eto spisuk s niakoi
optsii na test:
Proverka za ravenstva mezhdu promenlivite x i y,
ako promenlivite sa chisla:
x -eq y
Proveriava dali x
e
ravno na y
x -ne y
Proveriava dali x
ne
e ravno na y
x -gt y
Proveriava dali x
e
po-goliamo ot y
x -lt y
Proveriava dali x
e
po-malko ot y
Proverka za ravenstva mezhdu promenlivite x i y,
ako promenlivite sa tekst:
x = y
Proveriava dali x
e
sushtitata kato y
x != y
Proveriava dali x
ne
e sushtitata kato y
-n x
Proveriava dali x
ne e
prazen tekst
-z x
Proveriava dali x
e
prazen tekst
Ot gorniia primer edinstveniiat red, koito mozhe da
vi se stori po-truden za rabirane e sledniia:
x=$(expr $x + 1)
Tova koeto pravi tozi red e da uvelichi
stoinosta na x
s 1. No kakvo znachi $(...)
?
Dali e promenliva? Ne. Na praktika tova e nachin da
kazhete na shel interpretatora, che shte
izpulniavate komandata expr $x + 1
, i rezultata
ot tazi komanda shte bude prisvoen na x
.
Vsiaka komanda koiato bude zapisana v $(...)
shte bude izpulnena:
#!/bin/bash
me=$(whoami)
echo "I am $me."
Opitaite s tozi primer za da razberete kakvo
imam predvid. Gornata programka mozhe da bude
napisana po-sledniia nachin:
#!/bin/bash
echo "I am $(whoami)."
Sami si reshete koi ot nachinite e po-lesen za vas.
Ima i drug nachin da izpulnite komanda ili da
prisvoite razultata ot izpulnenieto na dadena
komanda na promenliva. Tozi nachin shte bude obiasnen
po-natatuk. Za sega izpolzvaite $(...)
.
until ... do ... done
Uslovniia operator until
e mnogo blizuk do while
.
Edinstvenata razlika e, che se obrushta smisula na uslovieto i se vzima predvid novoto znachenie.
Deistvieto na until operatora e "dokato(until)
tova uslovie e viarno, izpulniavai(do)
komandite". Eto primer:
#!/bin/bash
x=0
until [ "$x" -ge 10 ]; do
echo "Current value of x: $x"
x=$(expr $x + 1)
sleep 1
done
Tozi kod mozhe bi vi izglezhda poznat. Proverete
go i vizhte kakvo pravi. until
shte izpulniava
komandite dokato stoinosta na promenlivata x
e po-goliama ili ravna na 10. Kogato stoinosta na x
stane 10 tsikulut shte spre. Eto zashto poslednata
stoinost na x
koiato shte se izpechata e 9.
for ... in ... do ... done
for
se izpolzva koga iskate da prisvoite na dadena promenliva nabor ot stoinosti. Naprimer mozhete da napishete programa, koiato da izpechatva 10 tochki vsiaka sekunda:
#!/bin/bash
echo -n "Checking system for errors"
for dots in 1 2 3 4 5 6 7 8 9 10; do
echo -n "."
done
echo "System clean."
V sluchai, che ne znaete optsiiata -n
na
komandata echo
spira avtomatichnoto
dobaviane na nov red. Probvaite komandata vednuzh s
-n
optsiiata i vednuzh bez neia za da
razberete za kakvo stava duma. Promenlivata dots
preminava prez stoinostite ot 1 do 10. Vizhte
sledniia primer:
#!/bin/bash
for x in paper pencil pen; do
echo "The value of variable x is: $x"
sleep 1
done
Kogato startirate programata shte vidite che x
v nachaloto shte ima stoinost paper
, sled koeto
shte premine na sledvashtata stoinost, koiato e pencil
,
i sled tova pen
. Kogato svurshat stoinostite
prez koito minava tsikula izpulnenito mu
zavurshva.
Eto edna dosta polezna programa. Tia dobavia .html
razshirenie na vsichki failove v tekushtata
direktoriia:
#!/bin/bash
for file in *; do
echo "Adding .html extension to $file..."
mv $file $file.html
sleep 1
done
Ako ne znaete "*
" e "wild card character".
Tova shte reche "vsichko v tekushtata direktoriia",
koeto v nashiia sluchai predstavliava vsichki failove
v tazi direktoriia. Promenlivata file
shte
premine prez vsichki stoinosti, v tozi sluchai
failovete v tekushtata direktoriia. Sled koeto
komandata mv
preimenuva stoinostite na
promenlivata file
vuv takiva s .html
razshirenie.
case ... in ... esac
Uslovniia operator case
e blizuk do if
. Za predpochitane e da se izpolzva kogato imame
goliam broi usloviia koito triabva da budat
provereni. Vzemete za primer sledniia kod:
#!/bin/bash
x=5 # initialize x to 5
# now check the value of x:
case $x in
0) echo "Value of x is 0."
;;
5) echo "Value of x is 5."
;;
9) echo "Value of x is 9."
;;
*) echo "Unrecognized value."
esac
Operatora case
shte proveri stoinost na x
na koia ot 3-te vuzmozhnosti otgovaria. V tozi
sluchai purvo shte proveri dali stoinosta na x
e 0, sled koeto shte proveri za 5 i 9. Nakaia ako nikoe
ot usloviia ne e izpulneno shte se izpechata
suobshenieto "Unrecognized value.". Imaite predvid, che
"*
" oznachava "vsichko", i v tozi
sluchai tova oznachava "koiato i da e stoinost
razlichna ot posochenite". Ako stoinosta na x
e razlichna ot 0, 5, ili 9, to togava tia popada v
sluchaia "*
". Kogato izpolzvate case
vsiako uslovie triabva da zavurshva s dve ";".
Mozhe bi se chudite zashto da izpolzvate case
kogato mozhe da izpolzvate if
? Eto kak
izglezhda ekvivalentnata programa napisana s if
.
Vizhte koia programa e po-burza i po lesna za
chetene:
#!/bin/bash
x=5 # initialize x to 5
if [ "$x" -eq 0 ]; then
echo "Value of x is 0."
elif [ "$x" -eq 5 ]; then
echo "Value of x is 5."
elif [ "$x" -eq 9 ]; then
echo "Value of x is 9."
else
echo "Unrecognized value."
fi
Vizhte [ CHast 1|
CHast 2 |
CHast 3 |
CHast 4
]