Aritmetikai kifejezéseket kezelő parancsok

A UNIX szemléletmódja a legtöbbször nem támogatja az aritmetikai kifejezések használatát. Ez csak ritkán okoz problémát a használatban, leggyakrabban a következő fejezetben ismertetendő shellscript-ek írásakor van rájuk szükség. Két fontos olyan parancs van, ami elfogad idegen aritmetikát: a test és az expr. A test parancs arra szolgál, hogy egy objektumról (fájlról vagy karaktersorozatról) megtudjuk, hogy egy adott tulajdonsággal bír-e. Így például tesztelhetünk egy állományt aszerint, hogy létezik-e, végrehajtható-e, stb. Hasonlóképpen vizsgálhatjuk egy karaktersorozat tulajdonságait (be van-e állítva, mekkora a hossza, azonos-e egy másikkal, stb.) (Teljesebb opcióleírások megint csak a Minimanuálban szerepelnek.)

 

$ test -w /etc/group; echo $?

1

$ a=2; test $a -eq 2; echo $?

0

$ test "$a" = "02"; echo $?

1

$

A fenti példa, alapvető butuskasága ellenére megmutatja a test parancs három arcát. Az első esetben a /etc/group állományról szeretnénk megtudni, hogy létezik-e és írható-e, precízebben, írható-e a mi számunkra, mivel a parancs a hívó szempontjából vizsgálja az engedélyeket. A válasz nem, ezt mutatja az exit változó ($?) nullától különböző értéke. A második esetben, miután értéket adtunk az a változónak, azt teszteltük, hogy annak értéke azonos-e kettővel. Mivel a test parancs -eq opcióját használtuk, az egyébként alapértelmezésben stringként kezelt változót a Unix numerikus értékként kezelte, s numerikus összehasonlítást végzett. Harmadik példánkban viszont az = jel azt jelezte a Unix shell számára, hogy stringösszehasonlítást kell végrehajtania, s így a változót stringként kezelve hasonlította a '02' karakterekhez, amelyek így valóban nem egyeznek egymással.

Az expr parancs három, egymástól eléggé eltérő feladatra alkalmazható. Az első, és leggyakrabban használt funkciója, hogy az átadott argumentumlistát logikai vagy (egész) aritmetikai kifejezésként értékeli ki. A legegyszerűbb példa ennek szemléltetésére talán az alábbi:

$ expr 16 + 3

19

$ a=5; expr $a + 1

6

$

Az összeadáson kívül természetesen ismeri a kivonás, (-) a szorzás, (\*) az osztás (/) és a maradék képzés (%) műveleteket. Érdemes felfigyelni a parancs szintaktikájára, mert apróságból eredő nagy bosszúságtól óvhatjuk meg magunkat. Részint vegyük észre, hogy a kifejezés belsejében lévő műveleti jelet szóközök veszik körül, másrészt a shell számára értelmezhető karaktert mindig el kell fednünk a shell elől egy backslash karakterrel.

Összekapcsolhatunk kifejezéseket logikai ÉS (&) és VAGY (|) jelekkel, és használhatunk relációs operátorokat is.

$ a=1; expr $a >= 0

0

$

Az expr parancs következő két funkciója stringek illeszkedésének vizsgálatára szolgál. Az

expr var : pattern

megadás esetén az expr a var argumentumra próbálja meg illeszteni a pattern argumentumot, mint mintát, s az illeszkedő karakterek számát fogja kiírni. A mintaként használt második argumentum tetszőleges reguláris kifejezés lehet. Nézzük meg ezt két példán!

Az első esetben azt vizsgáljuk, hogy a munkakatalógusunk nevére hogyan illeszkedik az alapkatalógusunk neve, mint minta:

$ pwd; echo $HOME

/usr/users /usr/users/demo

$ expr `pwd` : $HOME

0

$

Az expr 0 értéket adott vissza, mert maga a minta hosszabb, mint a szöveg. Ha viszont fordítva, a munkakatalógusunk illeszkedését vizsgáljuk az alapkatalógusra...

$ expr $HOME : `pwd`

10

$

Ugyanennek a stringillesztéses funkciónak egy módosítása, hogy nem az illeszkedő karakterek számát íratjuk ki, hanem az illeszkedő stringrészletet. Ehhez az kell, hogy a pattern mintában a kiiratandó szövegrészt backslash karakterrel levédett kerek zárójelek közé írjuk. Az alábbi példában a basename parancs működését modellezzük: a megadott fájlnévről leszedjük az esetleges katalógusneveket, és csak a fájlnevet hagyjuk meg:

$ expr /usr/archive/src12.c : '.*/\(.*\)'

src12.c

$

(E megoldás a reguláris kifejezések illesztésének azon sajátosságát használja ki, hogy az illesztő algoritmus (balról jobbra haladva) mindig a lehető leghosszabb mintát próbálja az adott stringre illeszteni. Ennek pedig az a következménye, hogy a fenti példánkban az illesztő algoritmus a '.*/' mintát a fájlnévben szereplő legjobboldalibb '/' karakterig húzza ki, a zárójelek között megadott '.*' rovására - jelen esetben pedig éppen ez az, amit akartunk.)

 

Tartalomjegyzék