Operációs rendszerek 1. BASH programozás szintaktikai alapok Balla Tibor balla.tibor@inf.unideb.hu
BASH UNIX rendszerhéj GNU Project Bourne again - born again SH
Irodalom Bash Reference Manual (http://www.gnu.org/software/bash/manual/bashref.html) Büki András: Unix/Linux héjprogramozás, Kiskapu, Budapest, 2002 Chris F.A. Johnson: Pro Bash Programming, Apress, 2009 Cameron Newham, Bill Rosenblatt: Learning the bash Shell, O Reilly, 1998 Mendel Cooper: Advanced Bash-Scripting Guide (http://tldp.org/ldp/abs/html/)
Töltsétek le a http://www.inf.unideb.hu/~tballa/op/hrace.b ash állományt. Győződjetek meg róla, hogy rendelkezik-e futtatási jogokkal.( Ha nem, akkor adjatok neki.)./hrace.bash
Változó Egyszerű változó fogalom. Nincsenek adattípusok. Egy bash változó tárolhat számot, karaktert és karakterekből álló sztringet. A változókat nem kell külön deklarálni, a rájuk való hivatkozáskor automatikusan létrejönnek. Az egyenlőségjel operátorral adhatunk értéket a változónak. Az értékadással a változó automatikusan létrejön, és felveszi az értéket. Az $változó_név alakban hivatkozhatjuk a változó értékét.
Feladatok 1. uzenet= Hello Vilag echo $uzenet 2. V1=alma V2=Korte V3=1234 echo $V1 $V2 $V3
Belső változók Változó Leírás $# Parancssori paraméterek száma $- A héjprogramot végrehajtó héjnak átadott kapcsolók $? Az utoljára végrehajtott parancs visszatérési értéke $$ A futó program folyamatazonosítója (PID) $! A háttérben utoljára végrehajtott parancs folyamatazonosítója $n Az n-dik parancssori paraméter értéke (n 1) $0 A futó héjprogram neve. $* A parancssori paraméterek egyben egyetlen karakterláncként. ( $1 $2 $3... ) $@ A parancssori paraméterek külön-külön. ( $1 $2 $3 )
Idézőjelek használata... A változók értéke behelyettesítésre kerül a szövegben.... A változók értéke nem kerül behelyettesítésre a szövegben. ` utasítás ` (Alt Gr + 7) ~ $( utasítás ) Parancs behelyettesítés. (lásd később)
Feladatok V1=alma V2=korte echo Az $V1 és a $V2 finom gyumolcsok. echo Az $V1 és a $V2 finom gyumolcsok. echo `ls l`
Egyszerű utasítások A legelemibb utasítás típus. Szavak sorozata, melyet valamelyik vezérlő operátor zár le. (, &&, &, ;, ;;,, &, (, ) és az újsor). A szavak közül az első azonosítja magát a parancsot, a többi pedig a parancs argumentuma. Lehet: Külső Belső
Csővezetékek és & Pl: who cut -d ' ' -f 1 sort uniq -c sort -n head -n 1
Utasítás listák Csővezetékek vagy utasítások sorozata, melyben az elemek ;, &, &&, vagy karakterekkel vannak elválasztva, és opcionálisan &, ; vagy újsor karakterrel vannak lezárva. ;, & és újsor, &&
Összetett utasítások Iteratív konstrukciók Feltételes konstrukciók
for for name [ [in [words...] ] ; ] do commands ; done for (( expr1 ; expr2 ; expr3 )) ; do commands ; done Pl: for ciklus_valtozo in A B C D ; do echo $ciklus_valtozo ; done for ciklus_valtozo in A B C D ; do echo $ciklus_valtozo ; done for ciklus_valtozo in $(seq 1 5) ; do echo $ciklus_valtozo ; done for ciklus_valtozo in * ; do echo $ciklus_valtozo ; done for ciklus_valtozo in * a b c; do echo $ciklus_valtozo ; done for gyumolcs in Alma Korte Barack ; do rev $gyumolcs ; done for i in `users` ; do echo $i ; done for ((i=0;i<=10;i=i+1)) ; do echo $i ; done for true do echo true; done for ((i=0;false;i=i+1)) ; do echo $i ; done
while while kifejezés; do utasítások; done Pl: while true ; do echo "vegtelen ciklus" ; done while false; do echo ures ciklus" ; done while test ${g:=0} -lt 10 ; do echo $g ; g=$(expr $g + 1) ; done
until until kifejezes ; do utasitasok ; done Pl: until false; do echo "vegtelen ciklus" ; done until true; do echo ures ciklus" ; done until test ${g:=0} -gt 10 ; do echo $g ; g=$(expr $g + 1) ; done
if if kifejezes ; then utasítások; [elif kifejezes ; then utasítások;] [else utasítások;] fi Pl: if test -z 1; then echo Igaz; else echo Hamis; fi if echo then; then echo A; else echo B; fi if test -z 0 ; test -n 0 ; then echo Igaz; else echo Hamis; fi
case case word in [ [(] pattern [ pattern]...) command-list ;;]... Esac Pl: echo -n Adj meg egy állatot: " read ANIMAL echo -n A(z) ${ANIMAL}nak " case $ANIMAL in lo kutya macska) echo -n negy";; esac echo " laba van." ember strucc ) echo -n ket";; *) echo -n nem tudom hany laba van";;
select select name [in words...]; do commands; done Pl: select allat in kutya macska lo eger; do echo $allat; done select fname in *; do echo a valasztott $fname; done
break [n] Az alábbi konstrukciókból való kilépésre szolgál: for while until select Az n 1. Segítségével az n db körülvevő konstrukcióból léphetünk ki. for i in $(seq 1 12) do echo -n a for j in $(seq 1 5) do echo -n b break 2 done done echo
continue [n] Az alábbi konstrukciókban a következő iterációs lépésre léptet. for while until select Az n 1. Segítségével az n db körülvevő konstrukciót léptetjük tovább. for i in $(seq 1 12) do echo -n a for j in $(seq 1 10) do if [[ $((j % 2)) -eq 1 ]] then continue 2 fi echo -n b done done echo
Csoportosítás ( list ) {list;} Pl:! (echo a echo b) echo c
Feladatok Adjuk meg az alábbi parancsok kimenetét a nélkül, hogy azokat végrehajtanánk! 1. echo a echo b 2. ( echo a echo b ) echo c 3. echo a && ( echo b echo c ) 4. echo a echo b echo c 5. echo echo echo && echo echo echo 6. echo a & ; echo c 7. ;; 8. echo ;
Aritmetikai műveletek expr parancs (elavult) $(( művelet )) Pl: expr 5 + 2 expr 5 = 0 (echo $?)
Aritmetikai műveletek - Operátorok 1. id++ id-- 2. ++id --id 3. - + 4.! ~ 5. ** 6. * / % 7. + - 8. << >> 9. < > 10. ==!= 11. & 12. ^ 13. 14. && 15. 16. expr? expr : expr 17. = *= /= %= += -= <<= >>= &= ^= = 18. expr1, expr2
Aritmetikai műveletek Pl: echo $(( 5 + 2 )) echo $(( 5 * 12 )) v=1; echo $(( v++ )) v=1; echo $(( ++v )) echo $(( 3453 ** 2-45 * 17 * ( 4 + 2))) echo $(for v in $( seq 1 100); do echo $((v ** 2)); done)
Kiterjesztések {} kiterjesztés ~ kiterjesztés paraméter és változó kiterjesztés parancs behelyettesítés aritmetikai kiterjesztés
{ } Segítségével olyan karakterláncok listáját hozhatjuk létre, melyben már egy meglévő karakterláncba illeszthetünk be tetszőleges számú további karakterláncot. Pl: echo a{d,c,b}e echo a{uto,lma,blak,jto} echo {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z}{ a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z}{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z} for i in a{lma,jto,blak}fa ; do echo $i rev ; done
~ Ha helyére a $HOME értéke kerül behelyettesítésre. Pl: echo ~ echo ~/konyvtar
Paraméter és változó kiterjesztés 1. ${parameter: word} Ha a parameter értéke határozatlan, akkor a kifejezés értéke word lesz, de a parameter értéke nem változik. ${parameter:=word} Ha a parameter értéke határozatlan, akkor a parameter felveszi a word értéket, így a kifejezés értéke is word lesz. ${parameter:?word} Ha a parameter értéke határozatlan akkor a standard hiba kimenetre a word üzenet íródik ki. A parameter értéke nem változik. ${parameter:+word} Ha a parameter határozatlan, akkor a kifejezés értéke határozatlan marad, ám abban az esetben, ha a paraméternek van értéke, akkor a kifejezés éréke word lesz.
Paraméter és változó kiterjesztés 2. ${parameter:offset} A parameter karakterlánc első offset számú karakterét elhagyja. ${parameter:offset:length} A parameter karakterlánc első offset számú karakterét elhagyja, és az azt követő length számú karaktert adja vissza. ${!prefix*} és ${!prefix@} A prefix kezdetű változók nevét adja vissza. ${!name[@]} és ${!name[*]} A prefix kezdetű tömb változók nevét adja vissza.
Paraméter és változó kiterjesztés 3. ${#parameter} A kifejezés értéke a parameter hossza lesz. Abban az esetben, ha a parameter helyett a * vagy @ szerepel, akkor a pozicionális paraméterek számát adja vissza. Abban az esetben ha a parameter tömb, akkor a tömb elemszámát adja vissza. ${parameter#word} és ${parameter##word} # word minta legrövidebb első előfordulását eltávolítja a parameter tartalmából. ## word minta leghosszabb első előfordulását eltávolítja a parameter tartalmából. ${parameter%word} és ${parameter%%word} % word minta legrövidebb végső előfordulását eltávolítja a parameter tartalmából. %% word minta leghosszabb végső előfordulását eltávolítja a parameter tartalmából.
Paraméter és változó kiterjesztés 4. ${parameter/pattern/string} A pattern minta első előfordulását a string-re cseréli. Abban az esetben, ha a pattern / jellel kezdődik, akkor az összes előfordulást a string-re cseréli. ${parameter^pattern} és ${parameter^^pattern} ^ esetében a pattern-re illeszkdő első karaktert nagybetűsíti. ^^ esetében pattern-re illeszkdő összes karaktert nagybetűsíti. ${parameter,pattern} és ${parameter,,pattern}, esetében a pattern-re illeszkdő első karaktert kisbetűsíti.,, esetében pattern-re illeszkdő összes karaktert kisbetűsíti.
Parancs behelyettesítése `` (Alt Gr + 7) $( ) Pl: echo $( ls l )
Aritmetikai műveletek expr parancs (( )) $(( )) Pl: expr 5 + 2 expr 10 / 2
Aritmetikai műveletek - Operátorok 1. id++ id-- 2. ++id --id 3. - + 4.! ~ 5. ** 6. * / % 7. + - 8. << >> 9. < > 10. ==!= 11. & 12. ^ 13. 14. && 15. 16. expr? expr : expr 17. = *= /= %= += -= <<= >>= &= ^= = 18. expr1, expr2
Aritmetikai műveletek Pl: echo $(( 5 + 2 )) echo $(( 5 * 12 )) v=1; echo $(( v++ )) v=1; echo $(( ++v )) echo $(( 3453 ** 2-45 * 17 * ( 4 + 2))) echo $(for v in $( seq 1 100); do echo $((v ** 2)); done)
test, [ ], [[ ]] Az első három parancs visszatérési értéke a tartalmazott kifejezés kiértékelése után 0 vagy 1 attól függően, hogy az adott kifejezés igaz vagy nem. test ~ [ ] [[ ]] < > ==!= Pl: [[ 20 -gt 3 ]] && echo igaz echo hamis [[ 20 > 3 ]] && echo igaz echo hamis
test test [kifejezés] A test program egy állapottal (status) tér vissza, amely lehet 0 (igaz) vagy 1 (hamis) az kifejezés kifejezés logikai értékétől függően. A kifejezések lehetnek egy- vagy kétváltozósak.
test operátorok Fájlok -r file Igaz, ha a felhasználónak olvasási joga van a fájlra. -w file Igaz, ha a felhasználónak írási joga van a fájlra. -x file Igaz, ha a felhasználónak végrehajtási (keresési) joga van a fájlra. -o file Igaz, ha a felhasználó a fájl tulajdonosa. -z file Igaz, ha a fájl üres (nulla hosszúságú). -f file Igaz, ha a fájl közönséges állomány (nem katalógus, perifériameghajtó, stb.). -d file Igaz, ha a fájl katalógus.
test operátorok Sztringek -z s1 Igaz, ha s1 string hossza nulla -n s1 Igaz, ha s1 string hossza nagyobb mint nulla s1 = s2 Igaz, ha s1 és s2 stringek azonosak s1!= s2 Igaz, ha s1 és s2 stringek nem azonosak s1 Igaz, ha s1 nem null-string
test operátorok Aritmetikai kifejezések n1 -eq n2 Igaz, ha n1 = n2 n1 -ne n2 Igaz, ha n1 <> n2 n1 -gt n2 Igaz, ha n1 > n2 n1 -ge n2 Igaz, ha n1 >= n2 n1 -lt n2 Igaz, ha n1 < n2 n1 -le n2 Igaz, ha n1 <= n2
test operátorok Egyéb! Unáris negáló operátor -o VAGY operátor -a ÉS operátor (expr) Zárójelezés a kiértékelési sorrend megváltoztatásához.
(( )), $(( )) echo $(( 5 > 7 )) echo $? echo $(( 5 < 7 )) echo $? (( 5 < 7 )) echo $? (( 5 > 7 )) echo $? (( 5 + 5 )) echo $? (( 5 5 )) echo $? (( 0 )) echo $?
Feladatok 1. test -z 0 echo A; echo B 2. test -z echo A; echo B 3. for word in echo; do $word $word; done 4. for word in *; do echo $word; done 5. for word in a b c d; do echo $word; done echo e 6. for word in a b c d; do echo $word; done && echo e 7. for word in $(seq 1 10); do test 5 -gt 10 ; done echo e
Feladatok 1. if [[ 5 -lt 6 ]] ; then echo [[ 5 -lt 6 ]]; fi 2. if [[ 5 -lt 6 ]] ; then echo $(( 5-6 )) ; fi 3. if [[ 5 -lt 6 ]] ; then echo $( echo $(( 5 + 4 )) && echo 9 ) ; fi 4. while [[ ${var:=1} -le 100 ]] ; do echo $(( $var**2 )) && var=$(( ++var )) ; done 5. v=almafa && echo ${#v} 6. for i in $(seq 1 $(( $(v=almafa && echo ${#v})**2 ))) ; do [[ 0 -eq $(($i % 4)) ]] && echo $i ; done 7. N=100;R=$(( RANDOM % N )) && echo $R 8. echo $((RANDOM%200+100))
Feladatok 1. [[ $(( RANDOM % 2 )) -eq 1 ]] && echo fej echo iras 2. [[ -z 0 ]] echo A; echo B 3. case $(( 3**2 )) in 6) echo Hat;; 9) echo Kilenc;; esac 4. if [[ -z 1 ]]; [[ -n 1 ]]; then echo Igaz; else echo Hamis; fi 5. if true; then echo Igaz else Hamis; fi 6. if echo then; then echo A; else echo B; fi 7. if (( 1 )) ; then false; else true; fi && echo true echo false
Szavakra tördelés Az aritmetikai kiterjesztés, a parancs behelyettesítés és a paraméter kiterjesztés esetében, ha azok nem idéző jelek között találhatóak, akkor a shell szavakra tördeli azokat. A szavakra tördeléshez az $IFS változóban található karaktereket használja. <space><tab><newline>
$IFS Pl: 1. IFS="-"; read a b c d; 1 2 3 4 echo $a (echo $b) (echo $c) (echo $d) 2. IFS="-"; read a b c d; 1-2-3-4 echo $a echo $b echo $c echo $d
$IFS 3. for i in $(echo 1z2z3z4); do echo $i; done; IFS=z;for i in $(echo 1z2z3z4); do echo $i; done; IFS=z;for i in $(echo 1z2z3 4); do echo $i; done; IFS= z ;for i in $(echo 1z2z3 4); do echo $i; done; IFS= _z ;for i in $(echo 1_2z3 4); do echo $i; done;
Fájlnév kiterjesztés A shell a parancs minden szavát megvizsgálja. Ha az tartalmaz a *? [, karakterek közül egyet is, akkor az a szót mintának tekinti. Ezek után behelyettesíti ABC sorrendben a mintának megfelelő állománynevekkel. Ha nem talál egy állománynevet sem, akkor változatlanul hagyja a szót.
Minták megadása * Minden sztringre illeszkedik beleértve az üres sztringet is. Ha / jellel végződik, akkor könyvtárakat jelölünk vele.? Egyetlen karakterre illeszkedik. [ ] A felsorolt karakterek közül egyre illeszkedik. Hasonló a reguláris kifejezések karakterosztályaira. Ha a [ jelet! vagy ^ jel követi, akkor a felsorolt karaktereken kívül mindegyikre illeszkedik. Megadhatóak tartományok a - a jel segítségével.
Előredefiniált karakterosztályok alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
Minták megadása Jelölje a pattern-list az egy, vagy több jellel elválasztott mintát. Ekkor?(pattern-list) Az adott minták közül bármelyikkel egyezik. *(pattern-list) Az adott minták egyszer sem, vagy többször fordulnak elő. +(pattern-list) Az adott minták egyszer vagy többször fordulhatnak elő. @(pattern-list) Csak az egyik megadott mintával egyezik.!(pattern-list) Egyik megadott mintával sem egyezik.
Minták megadása A. karakterrel kezdődő állományneveknél expliciten ki kell tenni a pontot a minta elejére, különben a shell nem helyettesíti be azokat. Lehetőleg ne adjunk olyan állomány és könyvtárneveket, melyek *,? vagy [ és ] jelet tartalmaznak. ls > al[ma]?dat ls > alm.dat ls al[ma]?dat
Feladat echo? echo?? echo??? for i in???; do echo $i; done echo [[:alpha:]]* echo [[:num:]]? echo [[:digit:]]* echo [[:digit:]][[:digit:]] for i in *; do echo $i; done
Parancsok csoportosítása ( ) Parancsok egy listáját tartalmazza, melyek egy számukra létrehozott subshell-ben futnak. { ;} Parancsok egy listáját tartalmazza, melyek a jelenlegi shell környezetben futnak, nem hozunk létre számukra subshell-t.
Függvények A függvények segítségével létrehozhatunk parancsoknak egy olyan sorozatát, melyeket a későbbiekben a függvény nevével hivatkozva újra végrehajthatunk. [ function ] name () compound-command [ redirections ] A függvényeknek is vannak pozicionális paramétereik.
Függvények function lista() for i in *;do echo $i; done lista lista() for i in *;do echo $i "elem"; done lista gyumolcs() (echo alma;echo korte;echo szilva;) gyumolcs lista() for i in *;do echo $i -"; done >> kimenet.txt lista lista >>kimenet2.txt
Paraméterek $* Az IFS első karakterével tagolja az összes parancssori paramétert. $@ Az összes parancssori paraméter. között. ${N} Az N-dik paramérer értéke. N=1... $# A shellnek átadott pozicionális paraméterek száma. $- A shell hívásakor bekapcsolt opciók. $? Az utoljára végrehajtott parancs visszatérési értéke. $$ PID $0
Függvények Pl: function list()(ifs=w;echo $*;) function params() (for i in $* ;do echo $i; done;echo $#;echo $$;echo $0;)
Átirányítás Tetszőleges programot utasíthatunk, hogy a program a bemenetét ne a billentyűzetről várja, és a futás eredményeit ne képernyőre írja. Minden standard outputra író program kimenete átirányítható egy állományba. parancs > állomány_név (létrejön az állomány, ha már létezett akkor felülírja azt) parancs >> állomány_név (létrejön az állomány, ha már létezett akkor hozzáfűz az állomány végéhez) parancs >& állomány_név (az stderr és stdout átirányítása az adott állományba) parancs >! állomány_név (a noclobber shell változó beállításától függetlenül is végrehajtódik) Bármelyik program, mely a standard inputról várja a bemenetét tetszőleges állományból olvashat. parancs < állomány_név
File descriptor A Unix programok úgy dolgoznak fájlokkal, hogy a fizikai fájlhoz, annak a megnyitásakor egy nemnegatív egész számot rendelnek, amit "file descriptor"-nak nevezünk. A fájlra vonatkozó összes műveletet a file descriptor -ral végzik. Ez a file descriptor a Unix kernel és a programok belügye, a program használója fájlneveket ad meg. Kivétel a 0, 1, 2 descriptor, amikhez nem kapcsolódik fájl megnyitási művelet, mert a shell automatikusan megnyitja őket inputra(0) ill. outputra(1, 2). Sok Unix program használja ezeket. A standard input -ot (0), ha nem kap fájlnevet paraméterként, a standard output -ot (1) és a standard error -t (2) minden esetben. Tulajdonképpen ezek a szűrő programok.
Átirányítás (>& és <&) ls 2>&1 cat fájlnév Fájl stdout cat fájlnév 2>&1 stderr stdout cat fájlnév > másikfájl fájl stdout másikfájl cat fájlnév 2> másikfájl fájl stdout, stderr másikfájl cat fájlnév &> másikfájl #minden a fájlba ömlesztve
<<[-]delimiter Here documents delimiter Here Documents A delimiter-ig olvas a standard inputról. Pl: tr a-z A-Z <<VEGE cat <<EOF cat << EOF
Here Strings <<< word Pl: tr a-z A-Z <<< Hello Vilag!"
Tömbök Csak 1 dimenziós tömböket használhatunk 0-tól indexelődik Nincs méretkorlát és nem kell előre megadni, hogy mekkora vektort akarunk használni Ugyanúgy működik, mint a sima változók
Tömbök Létrehozás/Értékadás: ARRAY=(value1 value2... valuen) Ilyenkor a tömb első N elemének értéket adunk, azaz az ARRAY[0]-nak, ARRAY[1]-nek,..., ARRAY[N-1]-nek ARRAY[NUM]=value Ilyenkor egyetlen elemnek adunk értéket Egy tömb összes elemének kiírása: echo ${ARRAY[*]} Egy adott elem kiírása: echo ${ARRAY[2]}
Tömbök gyumolcsok=(alma korte barack szilva) echo $gyumolcsok echo ${gyumolcsok} echo ${gyumolcsok[0]} echo $gyumolcsok[0] echo ${gyumolcsok[1]} echo ${gyumolcsok[2]} echo ${gyumolcsok[3]} echo ${gyumolcsok[*]} IFS=ae;echo ${gyumolcsok[*]} IFS=x;gyumolcsok=(almaxkortexszilva) echo ${gyumolcsok[*]} gyumolcsok=(alma barack szilva [6]=korte) echo ${gyumolcsok[5]} echo ${gyumolcsok[6]}