„EDU::GAMF::Operációs rendszerek::Gyakorlatok” változatai közötti eltérés
(→cp) |
|||
| (65 közbenső módosítás ugyanattól a szerkesztőtől nincs mutatva) | |||
| 171. sor: | 171. sor: | ||
==== mv ==== | ==== mv ==== | ||
Az '''mv''' parancs segítségével fájlokat és könyvtárakat mozgathatunk. Ezzel a paranccsal nevezhetjük át a fájlrendszer elemeit. | |||
A próbálkozáshoz másoljuk le a /etc/passwd állományt, ha eddig nem tettük meg! | |||
<syntaxhighlight lang="bash"> | |||
cp /etc/passwd ./ | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="bash"> | |||
# passwd állomány átnevezése file-ra | |||
mv passwd file | |||
# nem fut le! | |||
# /etc/passwd állomány átnevezése file-ra | |||
mv /etc/passwd /etc/file | |||
# nem fut le! | |||
# /etc/passwd állomány áthelyezése /tmp-be | |||
mv /etc/passwd /tmp | |||
# nem fut le! | |||
# /etc/passwd állomány áthelyezése /tmp-be és közben átnevezés file-ra | |||
mv /etc/passwd /tmp/file | |||
</syntaxhighlight> | |||
A könyvtárak áthelyezéséhez (vagy átnevezéséhez) ez esetben nincs szükségünk a ''recursive'' (''-r'') jelölésre. | |||
==== rm ==== | ==== rm ==== | ||
Az '''rm''' parancs segítségével fájlokat és könyvtárakat törölhetünk. | |||
<syntaxhighlight lang="bash"> | |||
rm file | |||
</syntaxhighlight> | |||
Könyvtárak törléséhez alkalmaznunk kell a rekurzív jelölést: ''-r''. | |||
<syntaxhighlight lang="bash"> | |||
rm folder -r | |||
</syntaxhighlight> | |||
==== less ==== | ==== less ==== | ||
A '''less''' egy fájlnézegető, amelynek segítségével lapozhatunk billentyűzet segítségével a fájlokban. | |||
<syntaxhighlight lang="bash"> | |||
less /etc/passwd | |||
</syntaxhighlight> | |||
==== more ==== | |||
A '''more''' szintén egy fájlnézegető, de ennek segítségével csak előre lapozhatunk, visszafelé nem. | |||
<syntaxhighlight lang="bash"> | |||
more /etc/passwd | |||
</syntaxhighlight> | |||
==== which ==== | ==== which ==== | ||
A '''which'' program segítségével lekérdezhetjük, hogy az adott utasításhoz tartozó állomány melyik mappában található. | |||
<syntaxhighlight lang="bash"> | |||
# az ls parancs abszolút elérési útvonala | |||
which ls | |||
# a which parancs abszolút elérési útvonala | |||
which which | |||
# a man parancs elérési útvonala | |||
which man | |||
</syntaxhighlight> | |||
==== file ==== | ==== file ==== | ||
A '''file''' utasítás segítségével lekérdezhetjük, hogy egy adott állomány milyen típusú: futtatható állomány (ELF), ASCII stb. | |||
<syntaxhighlight lang="bash"> | |||
file /etc/passwd | |||
file /bin/ls | |||
</syntaxhighlight> | |||
==== echo ==== | ==== echo ==== | ||
Az '''echo''' mindent kiír a képernyőre, amit parancssori argumentumként adunk át neki. | |||
<syntaxhighlight lang="bash"> | |||
echo "Hello World" | |||
echo Hello World | |||
echo Ez egy teszt üzenet | |||
echo "Ez egy teszt üzenet" | |||
</syntaxhighlight> | |||
Láthatjuk, hogy idézőjeltől függetlenül minden megjelenik a képernyőn. Észrevehetjük azt is, hogy minden sor végén új sor karakter (enter) található, amit a "-n" kapcsoló segítségével kapcsolhatunk ki. | |||
<syntaxhighlight lang="bash"> | |||
echo -n "Hello world" | |||
</syntaxhighlight> | |||
==== cat ==== | ==== cat ==== | ||
A '''cat''' utasítás fájlokat képes összefűzni és az eredményt a képernyőre írja ki. | |||
<syntaxhighlight lang="bash"> | |||
# /etc/passwd és a /etc/profile fájlok összefűzése a képernyőn (ebben a sorrendben) | |||
cat /etc/passwd /etc/profile | |||
</syntaxhighlight> | |||
Egy gyakoribb felhasználási módja, hogy a fájlok tartalmát a képernyőre vessük - ez esetben nem fűzünk hozzá semmit a fájlhoz. | |||
<syntaxhighlight lang="bash"> | |||
# /etc/passwd és a <semmi> összefűzése és megjelenítése a képernyőn | |||
cat /etc/passwd | |||
</syntaxhighlight> | |||
==== head ==== | ==== head ==== | ||
A '''head''' utasítás segítségével a fájlok első N során írhatjuk ki a képernyőre. Alapértelmezetten N=10, így ha csak egy fájlnevet adunk neki, akkor annak legfeljebb 10 sorát fogja kiírni (ha van annyi). | |||
<syntaxhighlight lang="bash"> | |||
head /etc/passwd | |||
</syntaxhighlight> | |||
Az alapértelmezett N=10 értéket a ''-n'' kapcsoló segítségével módosíthatjuk | |||
<syntaxhighlight lang="bash"> | |||
head -n 5 /etc/passwd | |||
# a -n a dokumentáció elhagyható, ha a - után szám található | |||
head -5 /etc/passwd | |||
</syntaxhighlight> | |||
==== tail ==== | ==== tail ==== | ||
A '''tail''' hasonlóan működik, mint a '''head''', de ez esetben nem a fájl elejéről ír ki N sort, hanem a végéről. | |||
<syntaxhighlight lang="bash"> | |||
tail /etc/passwd | |||
</syntaxhighlight> | |||
Az alapértelmezett N=10 értéket a ''-n'' kapcsoló segítségével módosíthatjuk | |||
<syntaxhighlight lang="bash"> | |||
tail -n 5 /etc/passwd | |||
# a -n a dokumentáció elhagyható, ha a - után szám található | |||
tail -5 /etc/passwd | |||
</syntaxhighlight> | |||
==== wc ==== | ==== wc ==== | ||
==== | A '''wc''' utasítás segítségével statisztikai adatokat nyerhetünk ki egy fájlból (''word counter''): sorok, szavak, karakterek és bájtok száma. | ||
<syntaxhighlight lang="bash"> | |||
wc /etc/passwd | |||
</syntaxhighlight> | |||
Van lehetőségünk szűkíteni a visszaadott adatokat kapcsolók segítségével: | |||
{| class="wikitable" style="margin: 0px auto" | |||
|+ | |||
|- | |||
! Rövid kapcsoló !! Hosszú kapcsoló !! Leírás | |||
|- | |||
| -l || --lines || sorok számát adja vissza | |||
|- | |||
| -w || --words || szavak számát adja vissza | |||
|- | |||
| -c || --chars || karakterek számát adja vissza | |||
|- | |||
| || --bytes || bájtok számát adja vissza | |||
|} | |||
<syntaxhighlight lang="bash"> | |||
# sorok számát írja ki | |||
wc -l /etc/passwd | |||
# szavak számát írja ki | |||
wc -w /etc/passwd | |||
# bájtok számát írja ki | |||
wc --bytes /etc/passwd | |||
# sorok és szavak számát írja ki a képernyőre | |||
wc -l -w /etc/passwd | |||
</syntaxhighlight> | |||
==== find ==== | ==== find ==== | ||
A '''find''' utasítás segítségével kereshetünk a fájlrendszerben különböző attribútumok alapján. | |||
<syntaxhighlight lang="bash"> | |||
# passwd nevű fájl keresése a /etc könyvtárban | |||
find /etc -name passwd | |||
</syntaxhighlight> | |||
=== Programok csatornái === | === Programok csatornái === | ||
| 192. sor: | 354. sor: | ||
=== Parancsbehelyettesítés === | === Parancsbehelyettesítés === | ||
=== Feladatok === | |||
==== Szedjük ki a ''/etc/passwd'' állomány 20. sorát ==== | |||
<syntaxhighlight lang="bash"> | |||
# beolvassuk az első 20 sort és levágjuk az utolsót | |||
head -20 /etc/passwd | tail -1 | |||
</syntaxhighlight> | |||
==== Mondjuk meg egy keresett bináris típusát ==== | |||
<syntaxhighlight lang="bash"> | |||
# fájl elérési út lekérdezése | |||
# STDOUT => /bin/ls | |||
which ls | |||
# fájl típusának lekérdezése | |||
file /bin/ls | |||
# rakjuk össze: | |||
file `which ls` | |||
</syntaxhighlight> | |||
== 2. óra == | == 2. óra == | ||
A második órát az alap utasításokkal folytatjuk. Utána scriptek írásával | A második órát az alap utasításokkal folytatjuk. Utána scriptek írásával foglalkozunk, amelyben megtekintjük a különböző vezérlési szerkezeteket is. | ||
=== Parancsok és példák === | === Parancsok és példák === | ||
==== mcedit ==== | ==== mcedit ==== | ||
Az '''mcedit''' az '''mc''' (''Midnight Commander'') szerkesztője. A Midnight Commander testvére a Total Commander ősének, a Volkov Commandernek, ami szintén egy konzolos alkalmazás. A közös gyökerek miatt nagyon hasonló funkcionalitásokat érhetünk el ebben is, mint a TC-ben - érdemes megnyitni az '''mc''' utasítással, amit később az '''F10''' billentyűvel, vagy az alsó sorban arra a gombra kattintással tudunk bezárni. Ebben az alkalmazásban működik az egér is, így kényelmes használatot eredményez. Érdekesség, hogy a "tálcára helyezés" is megoldott, így a '''Ctrl+O''' billentyűkombinációkkal háttérbe küldhetjük és folytathatjuk dolgunkat a terminálon, majd ugyanezzel a kombinációval előtérbe is hívhatjuk. | |||
Az mcedit megnyitható az ''mc''-ből is, a szokásos F4-es billentyűvel - vagy az arra való kattintással. | |||
Az egér az mcedit-ben is működik! | |||
A másolás a szerkesztőben is hasonlóan működik, mint a kétpaneles fájltallózóban: F5 és F6 billentyűkkel másolhatunk illetve áthelyezhetünk sorokat. Kilépni az F10 billentyűvel, ESC-el tudunk, de ezt az ablakot is a háttérbe küldhetjük, ha szerkesztés közben terminált szeretnénk elérni (''CTRL+O''). | |||
<syntaxhighlight lang="bash"> | |||
mcedit /etc/passwd | |||
</syntaxhighlight> | |||
==== nano ==== | |||
A '''nano''' szintén egy szövegszerkesztő alkalmazás. | |||
Alul láthatjuk a segédletet, hogy milyen kombinációkkal milyen funkcionalitás érhető el. A szükségesebbek: | |||
* CTRL+K segítségével kivághatunk sorokat a vágólapra (shift+kurzorbillentyűk segítségével tört sorok is kijelölhetők) | |||
* CTRL+U Beilleszti a vágólap tartalmát az aktuális sorba | |||
* CTRL+O Menti a változásokat | |||
* CTRL+X Kilép, de megkérdezi, hogy menteni akarunk-e, ha vannak mentetlen változások | |||
<syntaxhighlight lang="bash"> | |||
nano /etc/passwd | |||
</syntaxhighlight> | |||
==== chmod ==== | ==== chmod ==== | ||
==== shift ==== | ==== shift ==== | ||
==== cut ==== | ==== cut ==== | ||
A '''cut''' parancs segítségével táblázatos adatokat szűrhetünk: kiválaszthatjuk, hogy mely oszlopokat szeretnénk megjeleníteni. A két legfontosabb kapcsolója a ''-f'' (''field''), ahol a megjelenítendő oszlopokat adhatjuk meg és a ''-d'' (''delimiter''), ahol az elválasztó karaktert állíthatjuk be. | |||
Általában a ''/etc/passwd'' állományon dolgozunk, mert ebben egy '':''-al elválasztott táblázat található. | |||
<syntaxhighlight lang="bash"> | |||
# a fájl első oszlopát szedi ki :-nál elválasztva, | |||
# tehát a felhasználónevet | |||
cut -f1 -d':' /etc/passwd | |||
# a fájl első és harmadik oszlopát adja vissza :-nál elválasztva, | |||
# tehát a felhasználónevet és az id-ját | |||
cut -f1,3 -d':' /etc/passwd | |||
# a fájl első három és hatodik oszlopát adja vissza :-nál elválasztva, | |||
# tehát a felhasználónevet, jelszót és a felhasználó id-ját, valamint a home könyvtárát | |||
cut -f1-3,6 -d':' /etc/passwd | |||
</syntaxhighlight> | |||
==== sort ==== | ==== sort ==== | ||
A '''sort''' utasítás segítségével rendezhetjük az adattömböt. | |||
<syntaxhighlight lang="bash"> | |||
# a passwd állomány rendezése a felhasználónév szerint - ez van elől | |||
sort /etc/passwd | |||
# fordított sorrend - reverse | |||
sort -r /etc/passwd | |||
</syntaxhighlight> | |||
Alapértelmezetten karakterek szerint rendez, tehát a számokat tartalmazó adatsorokat nem helyes sorrendben adja vissza. Ha számérték szerinti rendezést szeretnénk végrehajtani, akkor használjuk a ''-n'' opciót. | |||
<syntaxhighlight lang="bash"> | |||
# file egy számokat tartalmazó fájl - egy sor egy fájl | |||
sort -n file | |||
# fordított sorrend | |||
sort -r -n file | |||
</syntaxhighlight> | |||
==== tr ==== | ==== tr ==== | ||
A '''tr''' parancs segítségével karaktereket cserélhetünk ki egy fájlban. Ezen kívül nagyon hasznos tulajdonsága, hogy a kívánt ismétlődéseket el tudja távolítani, mintegy megtisztítva az adatsort. | |||
<syntaxhighlight lang="bash"> | |||
# az e betűt o-ra, az o betűt e-re cseréli ki | |||
echo "hello" | tr eo oe | |||
# A T betűt K-ra, az n betűt p-re cseréli ki | |||
echo "Tanar" | tr Tn Kp | |||
</syntaxhighlight> | |||
A fenti példák alapján nézzük meg, hogy mi történik: | |||
# A tr két pozicionális paraméterrel lett meghívva | |||
## Az első paraméter adja meg a lecserélendő karakterek halmazát | |||
## A második paraméter adja meg az új karakterek halmazát | |||
# A program végig megy a bemeneten és közben megvizsgálja, hogy az adott karakter megtalálható-e az első paraméterben | |||
## ha megtalálható, akkor lecseréli a karakterrel azonos pozícióban álló második paraméterben található értékre | |||
## ha nincs benne, akkor megy tovább | |||
# a metodika miatt keresztbe is lehet cserélni (pl. ''o''-t ''e''-re, ''e''-t ''o''-ra, mint az első példában). Gondoljuk végig, hogy ha nem így lenne, akkor az először lecserélt ''e'' betűnek a végén ''o'' betűre kéne cserélődnie. | |||
==== if ==== | ==== if ==== | ||
Az '''if''' segítségével elágazásokat hozhatunk létre, mint minden más programozási nyelven. A szerkezet a következőképp néz ki: | |||
<syntaxhighlight lang="bash"> | |||
if KIFEJEZÉS | |||
then | |||
elif KIFEJEZÉS | |||
elif KIFEJEZÉS | |||
else | |||
fi | |||
</syntaxhighlight> | |||
Természetesen az egyes feltételek kihagyhatók, így készíthetünk egy egyszerű '''if''' elágazást is: | |||
<syntaxhighlight lang="bash"> | |||
if KIFEJEZÉS | |||
then | |||
fi | |||
</syntaxhighlight> | |||
Ha egy sorban szeretnénk leírni (nem scriptben), akkor a következőképpen tehetjük meg: | |||
<syntaxhighlight lang="bash"> | |||
if KIFEJEZÉS; then UTASÍTÁS1; UTASÍTÁS2; elif KIFEJEZÉS; then UTASÍTÁS1; UTASÍTÁS2; else UTASÍTÁS; fi | |||
</syntaxhighlight> | |||
<big>'''KIFEJEZÉS'''</big><br /> | |||
Egy olyan program, amelynek a visszatérési értéke hasznos információkat hordoz a futás eredményét tekintve. Ne feledjük el, hogy a '''return''' kulcsszóval tudunk ilyen értéket generálni C/C++ kódok esetében. Lássunk egy példát: | |||
<syntaxhighlight lang="c"> | |||
#include <stdio.h> | |||
int main() { | |||
if ( 10 % 2 == 0 ) return 0; | |||
else return 1; | |||
} | |||
</syntaxhighlight> | |||
A fenti program visszatérési értéke információval szolgál számunkra, hogy a 10 osztható-e kettővel, avagy sem. Ez az érték vizsgálható az '''if''' segítségével és a válasz függvényében más-más kódokat hajthatunk végre. | |||
A kiértékelés ellentétes a megszokott módszerhez képest (ahol minden igaz, aminek az értéke nem 0). | |||
<syntaxhighlight lang="bash"> | |||
# ha a KIFEJEZÉS 0 értéket ad vissza, akkor IGAZ az állítás, tehát az if-en belüli kód fut | |||
if KIFEJEZÉS => 0 | |||
then | |||
.... | |||
else | |||
.... | |||
fi | |||
# ha a KIFEJEZÉS nem 0 értéket ad vissza, akkor HAMIS az állítás, tehát az else-n belüli kód fut | |||
if KIFEJEZÉS => != 0 | |||
then | |||
... | |||
else | |||
... | |||
fi | |||
</syntaxhighlight> | |||
A programozási nyelvek tanításakor ezért térünk vissza 0-s értékkel ('''return 0;'''), a programunk végén, és hiba esetén 1, vagy annál nagyobb értékkel. | |||
==== test ==== | |||
A '''test''' parancs logikai függvényeket értékel ki és | |||
* '''0''' értéket ad vissza, ha az eredmény '''IGAZ''', | |||
* '''1''' értéket ad vissza, ha az eredmény '''HAMIS''' | |||
Az '''if''' utasítással együtt szoktuk használni, de természetesen ettől független is meghívható. | |||
<syntaxhighlight lang="bash"> | |||
# megtörténik a logikai kiértékelés, eldől, hogy a két string egyezik-e | |||
test "text1" == "text2" | |||
# kiírjuk a képernyőre a test utasítás visszatérési értékét | |||
echo $? | |||
</syntaxhighlight> | |||
'''if''' utasítással a következőképp használhatjuk: | |||
<syntaxhighlight lang="bash"> | |||
# hamis | |||
if test "text1" == "text2" | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
# igaz | |||
if ! test "text1" == "text2" | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
#igaz | |||
if test "text1" != "text2" | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
</syntaxhighlight> | |||
Elérhető egy ''alias'', aminek segítségével olvashatóbbá tehetjük a '''test''' utasítást. Ez a '''[ ]''' pár. | |||
<syntaxhighlight lang="bash"> | |||
if [ "text1" == "text2" ] | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
</syntaxhighlight> | |||
'''Ügyeljünk rá, hogy a ''['' és a '']'' zárójelek mellett ''whitespace'' karakterek vannak. Ha ezeket kihagyjuk, akkor hibát fogunk kapni!''' | |||
A számok ellenőrzése BASH környezetben körülményesebb, mivel itt minden karakterláncnak számít. Emiatt a következő utasítás sorozat nem várt eredménnyel zárul: | |||
<syntaxhighlight lang="bash"> | |||
if [ "1000" <= "20" ] | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
</syntaxhighlight> | |||
'''Az eredmény''': igaz. De tudjuk, hogy ez az eredmény nem igaz, a BASH mégis így értékelte ki. Az oka, hogy az első karaktereket tekintve (''1'' és ''2'') elmondható, hogy az ''1''-es hamarabb van az ABC-ben (kódtáblában), mint a ''2'', így az ''1000''-nek kisebbnek kell lennie (mintha a "alma" és "körte" lenne összehasonlítva, hogy melyik következik előbb az ABC-ben). | |||
Ahhoz, hogy a '''test''' utasítás karakterek helyett számként dolgozza fel a paramétert, kapcsolót kell használnunk: | |||
{| class="wikitable" style="margin: 0px auto;" | |||
|+ | |||
|- | |||
! Kapcsoló !! Angol megnevezés !! Magyar megnevezés | |||
|- | |||
| -eq || Equals || Egyenlő | |||
|- | |||
| -ne || Not Equals || Nem egyenlő | |||
|- | |||
| -lt || Lower than || Kisebb, mint | |||
|- | |||
| -le || Lower than or equals || Kisebb vagy egyenlő | |||
|- | |||
| -gt || Greather than || nagyobb, mint | |||
|- | |||
| -ge || Greather than or equals || Nagyobb vagy egyenlő | |||
|} | |||
<syntaxhighlight lang="bash"> | |||
if [ 1000 -le 20 ] | |||
then | |||
echo "igaz" | |||
else | |||
echo "hamis" | |||
fi | |||
</syntaxhighlight> | |||
'''Az eredmény''': Az elvártaknak megfelelően HAMIS. | |||
==== for ==== | ==== for ==== | ||
A '''for''' utasítás segítségével egy lista elemein mehetünk végig. Hasonlóan működik, mint a modern programozási nyelvekben a ''foreach''. | |||
Legegyszerűbben a következő utasítással tesztelhetjük, ahol a bemeneti listát soronként látjuk viszont a képernyőn: | |||
<syntaxhighlight lang="bash"> | |||
for i in 1 2 3 4 5 6 | |||
do | |||
echo $i | |||
done | |||
</syntaxhighlight> | |||
Természetesen van lehetőségünk a listát más program kimenetéből kinyerni a parancsbehelyettesítés segítségével: | |||
<syntaxhighlight lang="bash"> | |||
for i in `ls` | |||
do | |||
echo $i | |||
done | |||
</syntaxhighlight> | |||
A '''for''' gyakorlatilag a pozicionális paramétereken megy végig, tehát egy lista elem a $1, egy másik listaelem a $2. Tudjuk, hogy ha szóközök között adjuk meg, akkor szóközt is tartalmazhat a paraméterünk. Lássunk egy példát: | |||
<syntaxhighlight lang="bash"> | |||
for i in "1 2 3" "4 5 6" | |||
do | |||
echo $i | |||
done | |||
</syntaxhighlight> | |||
Ez esetben a képernyőn két sor jelenik meg: ''1 2 3'' és ''4 5 6''. Azonban a parancsbehelyettesítés nem alkalmaz az idézőjelhez hasonló technikát, tehát azt alkalmazva minden szó (szóközökkel határolt karaktersorozat) új pozicionális paramétert jelent. Lássunk egy az előzőhöz hasonló példát: | |||
<syntaxhighlight lang="bash"> | |||
for i in `echo "1 2 3 4 5 6"` | |||
do | |||
echo $i | |||
done | |||
</syntaxhighlight> | |||
Ez esetben hat sor jelenik meg, benne egy-egy számmal, tehát az '''echo "1 2 3 4 5 6"''' kimenetét szóközönként vágta fel. | |||
==== while ==== | ==== while ==== | ||
A '''while''' utasítás, mint minden programozási nyelvben, itt is felfogható úgy, mint egy többször lefutó '''if'''. Éppen ezért a szintaktikájuk megegyezik, csupán a feltételek megírásával kell óvatosan bánnunk, hogy a ciklus mag akkor és addig fusson, ameddig mi azt szeretnénk. A '''while''' ciklusnál ugyanazokat az alkalmazásokat írhatjuk be a '''KIFEJEZÉS''' helyére, mint az '''if''' esetében. | |||
<syntaxhighlight lang="bash"> | |||
while KIFEJEZÉS | |||
do | |||
done | |||
</syntaxhighlight> | |||
Például ha azt akarjuk, hogy egy ciklus addig fusson, amíg meg nem jelenik egy fájl a fájlrendszerben, akkor azt a következőképp vezethetjük le: | |||
<syntaxhighlight lang="bash"> | |||
# ellenőrzi, hogy a fájl elérhető-e | |||
test -f "file.txt" | |||
# ez esetben egyetlen kísérletet teszünk, de nem várjuk meg, hogy oda kerüljön, amennyiben nincs ott | |||
if test -f "file.txt" | |||
then | |||
echo "a fájl létezik" | |||
else | |||
echo "A fájl nem létezik" | |||
fi | |||
# várakozunk, amíg a feltétel nem lesz igaz, tehát a fájl nem kerül oda | |||
while ! test -f "file.txt" | |||
do | |||
echo "várakozunk" | |||
done | |||
echo "a fájl létezik" | |||
# test parancs helyettesítése []-el | |||
while ! [ -f "file.txt" ] | |||
do | |||
echo "várakozás" | |||
done | |||
echo "a fájl létezik" | |||
</syntaxhighlight> | |||
A while ciklusnál érdemes megemlíteni a '''until''' utasítást, ami annyiban tér el, hogy a feltétel kiértékelését invertálni kell - tehát ami igaz a '''while''' esetében, az hamis az '''until''' esetében és fordítva. Így a fenti feladatot megvalósíthatjuk invertálás nélkül, az until utasítással is: | |||
<syntaxhighlight lang="bash"> | |||
until test -f "file.txt" | |||
do | |||
echo "várakozás" | |||
done | |||
echo "a fájl létezik" | |||
</syntaxhighlight> | |||
==== seq ==== | ==== seq ==== | ||
A '''seq''' utasítás egy listát generál számunkra, amelyben a megadott lépésszámmal, a megadott legkisebb értéktől a megadott legnagyobb értékig szerepelnek a számok. | |||
<syntaxhighlight lang="bash"> | |||
# számok 1-10-ig | |||
seq 10 | |||
# számok 5-10-ig | |||
seq 5 10 | |||
# számok 3-tól 10-ig 2-esével | |||
seq 3 2 10 | |||
</syntaxhighlight> | |||
A '''seq''' utasítást általában a '''for''' ciklus listájában használjuk, hogy elő tudjuk állítani az indexeket. | |||
<syntaxhighlight lang="bash"> | |||
for i in `seq 3 2 10` | |||
do | |||
echo $i | |||
done | |||
</syntaxhighlight> | |||
==== read ==== | ==== read ==== | ||
A '''read''' utasítás segítségével a STDIN-ről kérhetünk be információt változóba/változókba. Ha több változót sorolunk fel, akkor a bemenetet szóközöknél vágja el. | |||
<syntaxhighlight lang="bash"> | |||
# beolvasás var-ba | |||
# STDIN => teszt | |||
# var => teszt | |||
# STDIN => teszt szöveg | |||
# var => teszt szöveg | |||
read var | |||
# beolvasás fname és lname változókba | |||
# STDIN => Attila Farkas | |||
# fname => Attila | |||
# lname = Farkas | |||
# STDIN => Attila | |||
# fname => Attila | |||
# lname => <üres> | |||
# STDIN => Attila Farkas OPSYS | |||
# fname => Attila | |||
# lname => Farkas OPSYS | |||
read fname lname | |||
# beolvasás három változóba. Ha a felhasználó az utasításokkal szemben több szót adott meg, akkor így biztosíthatjuk, hogy ne legyen szóköz az első két változóban | |||
# STDIN => Attila Farkas | |||
# fname => Attila | |||
# lname => Farkas | |||
# tmp => <üres> | |||
# STDIN => Attila Farkas OPSYS meg valami más | |||
# fname => Attila | |||
# lname => Farkas | |||
# tmp => OPSYS meg valami más | |||
read fname lname tmp | |||
</syntaxhighlight> | |||
Az utóbbi esetben hibaüzenet is generálható, ha megvizsgáljuk, hogy a ''tmp'' változó értéke üres-e: | |||
<syntaxhighlight lang="bash"> | |||
echo -n "Adja meg a teljes nevét: " | |||
read fname lname tmp | |||
# -n => nem üres? | |||
# -z => üres? | |||
if [ -n "$tmp" ] | |||
then | |||
echo "Valamit elhibáztál" | |||
exit 1 | |||
fi | |||
</syntaxhighlight> | |||
Ha szeretnénk ellenőrzött bekérést végrehajtani: | |||
<syntaxhighlight lang="bash"> | |||
tmp="start value" | |||
while [ -n "$tmp" ] | |||
do | |||
echo -n "Adja meg a teljes nevét FNAME LNAME formátumban: " | |||
read fname lname tmp | |||
if [ -n "$tmp" ] | |||
then | |||
echo "Valamit elrontottál!" | |||
# ez esetben nem lépünk ki, mert bekérjük újra | |||
fi | |||
done | |||
</syntaxhighlight> | |||
==== expr ==== | |||
Az '''expr''' parancs segítségével tudunk matematikai műveleteket végrehajtani. Mivel a BASH-ben minden változó karakterlánc, így nem tudunk közöttük műveletet végezni. Az '''expr''' a paramétereket belül számként kezeli. '''Csak egész számokkal tud dolgozni!''' | |||
<syntaxhighlight lang="bash"> | |||
# a képernyőre kerül az eredmény | |||
expr 1 + 2 | |||
expr 4 * 4 | |||
# csak egész számot ír ki | |||
expr 3 / 2 | |||
</syntaxhighlight> | |||
Ha tört számokkal kell dolgoznunk, akkor a következőket tehetjük: | |||
# eltávolítjuk a törtrészt | |||
# felszorozzuk 10^n-nel, ahol n a törtrész számjegyeivel egyezik meg (pl. 10.02-t 100-al kell szorozni). Az egész térben elvégzett művelet eredményét később vissza osztjuk ugyanannyival, amennyivel korábban felszoroztuk. '''Ez nem egy egyszerű feladat, hiszen a tört számot egyáltalán nem kezeli az expr, tehát cut, wc és egyéb parancsokkal kell kialakítanunk a számot, ahogy utána szét is kell darabolnunk azt.''' | |||
# Másik környezetet használunk, ahol tudunk számokat is kezelni - '''ez a ZH-n nem elfogadott''' | |||
A lehetőségek közül csak az elsőt, a ZH-n teljes mértékben elfogadott megoldást mutatom be: | |||
<syntaxhighlight lang="bash"> | |||
# a 3.4-et és a 1.2-őt kell összeadnunk. | |||
# ennek eredménye 3 | |||
echo "3.4" | cut -d'.' -f1 | |||
# ennek eredménye 1 | |||
echo "1.2" | cut -d'.' -f1 | |||
# rakjuk össze | |||
expr `echo "3.4" | cut -d'.' -f1` + `echo "1.2" | cut -d'.' -f1` | |||
</syntaxhighlight> | |||
=== Feladatok parancsokhoz === | |||
==== Írassuk ki a /etc/passwd több sorát ==== | |||
Több választási lehetőségünk van: | |||
* ha a kiírandó sorszámok valamilyen logikát követnek (minden második, harmadik stb.), akkor használhatjuk a '''seq''' utasítást | |||
* ha nincs logika a sorszámokban, akkor kézzel kell elkészítenünk a listát | |||
<big>'''Logikát tartalmazó sorszámok'''</big><br> | |||
''Írassuk ki minden harmadik sor tartalmát''<br> | |||
<syntaxhighlight lang="bash"> | |||
# határozzuk meg a seq tartományát | |||
# min: 1 | |||
# max: ahány sora van a fájlnak | |||
# max érték meghatározás | |||
# a változó létrehozást lentebb tárgyaljuk | |||
max=`cat /etc/passwd | wc -l` | |||
# lista meghatározása for ciklushoz | |||
# 1-től $max-ig hármasával | |||
seq 1 3 $max | |||
# Rakjuk össze | |||
for i in `seq 1 3 $max` | |||
do | |||
head -$i /etc/passwd | tail -1 | |||
done | |||
</syntaxhighlight> | |||
<big>'''Logikát nem tartalmazó sorszámok'''</big><br> | |||
''Írassuk ki a 2., 5., 10. és 11. sorokat''<br> | |||
<syntaxhighlight lang="bash"> | |||
for i in `2 5 10 11` | |||
do | |||
head -$i /etc/passwd | tail -1 | |||
done | |||
</syntaxhighlight> | |||
==== Fájlok ellenőrzése és másolása ==== | |||
Másoljuk át a /etc/passwd állományt egy könyvtárba (~/test/destination). Ha a célkönyvtár nem létezik, akkor hozzuk létre. Ha a célkönyvtár és a fájl is létezik, akkor írjunk ki hibaüzenetet. | |||
<syntaxhighlight lang="bash"> | |||
# forrás fájl létezésének vizsgálata | |||
test -f /etc/passwd | |||
# célfájl létezésének vizsgálata | |||
test -f ~/test/destination/passwd | |||
# mappa létezésének vizsgálata | |||
test -d ~/test/destination | |||
# rakjuk össze | |||
# ha a forrásfájl nem létezik | |||
if ! test -f /etc/passwd | |||
then | |||
echo "A forrásfájl nem létezik" | |||
# ha a célfájl létezik | |||
elif test -f ~/test/destination/passwd | |||
then | |||
echo "A fájl már létezik" | |||
# ha a cél mappa nem létezik | |||
elif ! test -d ~/test/destination | |||
then | |||
# mappa létrehozás - szülőkönyvtárakat is, ha nem léteznek | |||
mkdir -p ~/test/destination | |||
# fájl belemásolása | |||
cp /etc/passwd ~/test/destination | |||
# ha a célfájl nem létezik, de a célmappa igen | |||
else | |||
# a fájlt bemásoljuk a könyvtárba | |||
cp /etc/passwd ~/test/destination | |||
fi | |||
</syntaxhighlight> | |||
=== Script létrehozása === | === Script létrehozása === | ||
| 218. sor: | 891. sor: | ||
=== Változók === | === Változók === | ||
== 3. óra == | == 3. óra == | ||
| 225. sor: | 896. sor: | ||
=== Reguláris kifejezés szerkezete === | === Reguláris kifejezés szerkezete === | ||
A reguláris nyelvek atomokból, lezártakból épül fel, amelynek az eredménye az úgynevezett „összetettek”. | |||
==== Atomok ==== | |||
Az atomok egy karakterre illeszkednek a sorban. | |||
{| class="wikitable" style="margin: 0px auto;" | |||
|- | |||
! Atom !! jelentés | |||
|- | |||
| betűk, számok || saját magukra illeszkednek | |||
|- | |||
| ^ || sor elejére illeszkedik (csak egyszer lehet a legelején) | |||
|- | |||
| $ || sor végére illeszkedik (csak egyszer lehet a legvégén) | |||
|- | |||
| [abc] || halmaz: minden benne lévő elemre illeszkedik | |||
|- | |||
| [^abc] || inverz halmaz: egyetlen benne lévő elemre sem illeszkedik | |||
|- | |||
| . || mindenre illeszkedik | |||
|- | |||
|} | |||
==== Lezártak ==== | |||
A lezártak ismétlődéseket fogalmaznak meg egy atomra vonatkozóan. '''Lezárt csak atom után helyezkedhet el!''' | |||
{| class="wikitable" style="margin: 0px auto;" | |||
|- | |||
! Lezárt !! jelentés | |||
|- | |||
| * || az atomot 0 és végtelen között akárhányszor ismételheti | |||
|- | |||
| + || az atomot 1 és végtelen között akárhányszor ismételheti | |||
|- | |||
| ? || az atomot 0 és 1 között akárhányszor ismételheti | |||
|- | |||
| {n} || az atom pontosan n-szer fordul elő egymás mellett | |||
|- | |||
| {n,m} || az atomot n és m között akárhányszor ismételheti | |||
|- | |||
| {n,} || az atomot n és végtelen között akárhányszor ismételheti | |||
|- | |||
| {,m} || az atomot 0 és m között akárhányszor ismételheti | |||
|- | |||
|} | |||
==== Összefűzöttek ==== | |||
Az atomok és a lezártak egymás után írt sorozata. | |||
A lezártaknál fontos kitétel volt, hogy csak atom után lehet írni. '''Egy összefűzött újra atomizálható''' a ( ) karakterekkel. | |||
Az összefűzöttek tartalmazhatnak uniót (|), ahol több szabály közül bármelyik megvalósulhat egy sikeres illesztéshez. | |||
=== Parancsok és példák === | === Parancsok és példák === | ||
Ez egy teszt szöveg, amin próbálkozunk. | |||
A fenti szöveget alapul véve, a következő reguláris kifejezéseket hozhatjuk létre: | |||
{| class="wikitable" style="margin: 0px auto;" | |||
! Reguláris kifejezés !! Illeszkedik? || Magyarázat | |||
|- | |||
| E || Igen || Van a sorban E betű | |||
|- | |||
| a || Igen || Van a sorban a betű | |||
|- | |||
| b || Nem || Nincs a sorban b betű | |||
|- | |||
| ^E || Igen || A sor elején van az E betű | |||
|- | |||
| ^A || Nem || Nincs a sor elején A betű | |||
|- | |||
| ^e || Nem || nincs a sor elején e betű | |||
|- | |||
| .$ || Igen || Bármilyen karakter lehet a sor végén | |||
|- | |||
| \. || Igen || . van a sor végén | |||
|- | |||
| k$ || Nem || Nincs k a sor végén | |||
|- | |||
| egy || igen || Van a sorban „egy” string | |||
|- | |||
| egység || Nem || Nincs a sorban egység string | |||
|- | |||
| egy* || Igen || eg kötelező, y 0 vagy végtelenszer lehet (egy, egyy, egyyy, egyyyy ...) | |||
|- | |||
| l*egy || Igen || l 0 vagy végtelen, eg kötelező (eg, leg, lleg, llleg, lllleg ...) | |||
|- | |||
| l+egy || Nem || Nincs a szövegben "l+egy" string | |||
|- | |||
| l\+egy || Nem || l 1 vagy végtelen hosszú, egy kötelező (legy, llegy, lllegy, llllegy ...) | |||
|- | |||
| (egy) || Nem || Nincs a sorban "(egy)" string | |||
|- | |||
| \(egy\) || Igen || Van a sorban "egy" string | |||
|- | |||
| \(egy\)* || Igen || Van a sorban legalább 0-szor "egy" string | |||
|- | |||
| \(egy\)\+ || Igen || Van a sorban legalább 1-szer "egy" string | |||
|- | |||
| \(egy\)\{2\} || Nem || Nincs a sorban pontosan kétszer "egy" string | |||
|- | |||
| [a-z] || Igen || Vannak benne kisbetűk | |||
|- | |||
| [A-Z] || Igen || Van benne nagy betű | |||
|- | |||
| ^[A-D] || Nem || Nincs a sor elején A-D tartományban betű | |||
|- | |||
| ^[A-Z] || Igen || Nagy betű van a sor elején | |||
|- | |||
| ^[A-Z].*\.$ || Igen || Nagybetűvel kezdőik, középen bármi lehet és ponttal végződik a sor. | |||
|- | |||
| [0-9] || Nem || Nincs számjegy a sorban | |||
|- | |||
| .* || Igen || Mindenre illeszkedik, bármilyen hosszan (üres sorra is) | |||
|- | |||
| ^$ || Nem || Csak az üres sorra illeszkedik | |||
|- | |||
| ^.\+$ || Igen || Mindenre illeszkedik, kivéve az üres sorra | |||
|} | |||
A következő kifejezés szintén illeszkedik: | |||
^[A-Z].*\(egy\)\|\(kettő\).*\.$ => A sor elején nagybetűvel kezdődik, van a közepén valahol benne "egy" vagy "kettő" karakterlánc és ponttal végződik. A köztes karakterek értéke nincs megszabva. | |||
==== grep ==== | ==== grep ==== | ||
A '''grep''' utasítás segítségével végezhetünk el reguláris kifejezés, tehát minta illesztést fájlokon. Amennyiben nem adunk meg fájl paramétert, a STDIN csatornát olvassa. Az eredmények a STDOUT-ra íródnak. | |||
{| class="wikitable" style="margin: 0px auto" | |||
|+ Fontosabb kapcsolók | |||
|- | |||
! Rövid név !! Hosszú név !! Magyarázat | |||
|- | |||
| -c || --count || Megszámolja az illeszkedő sorokat | |||
|- | |||
| -o || --only-matching || Csak a mintára illeszkedő részt írja ki (nem a teljes sort) | |||
|- | |||
| -n || --line-number || Megszámozza a sorokat (a fájl alapján, nem a megjelenítés szerint) | |||
|} | |||
===== Példa ===== | |||
<syntaxhighlight lang="bash"> | |||
# nologin környezetet futtató felhasználók listája a rendszerben | |||
grep "nologin" /etc/passwd | |||
cat /etc/passwd | grep "nologin" # STDIN-en érkező adatok szűrése | |||
# bash környezetet futtató felhasználók listája a rendszerben | |||
grep "bash" /etc/passwd | |||
cat /etc/passwd | grep "bash" # STDIN-en érkező adatok szűrése | |||
</syntaxhighlight> | |||
===== Példa 2 ===== | |||
Írjunk egy scriptet, amely a /bin/bash futtatási környezetet kapó felhasználók nevét kiírja a képernyőre. | |||
<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
# a fájl, amin dolgozunk | |||
file="/etc/passwd" | |||
# a fájl sorainak száma | |||
lines=`cat $file | wc -l` | |||
# végig megyünk a fájl sorain | |||
for i in `seq 1 $lines`; do | |||
# itt kapjuk meg az i. sort | |||
line=`head -$i $file | tail -1` | |||
# kiszedjük a shell környezetet | |||
shell=`echo $line | cut -f7 -d':'` | |||
# ha ez "/bin/bash", akkor kivágjuk a sor első oszlopát, ezt írhatjuk a képernyőre | |||
if test $shell == "/bin/bash"; then | |||
echo $line | cut -f1 -d':' | |||
fi | |||
done | |||
</syntaxhighlight> | |||
A fenti script futási ideje: 0.227s | |||
<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
# a fájl, amin dolgozunk | |||
file="/etc/passwd" | |||
# szűrjük ki a sorokat, amelyeknek a végén a "/bin/bash" karakterlánc található | |||
# és a kapott eredményhalmaznak vágjuk ki az első oszlopát | |||
# a kapott eredményhalmaz még mindig megfelel a /etc/passwd eredeti formátumának, | |||
# csak a sorok számát csökkentettük a szűrési feltételnek megfelelően! | |||
grep "/bin/bash$" $file | cut -f1 -d':' | |||
</syntaxhighlight> | |||
A fenti script futási ideje: 0.003s | |||
===== MAC cím parser ===== | |||
Legyen egy MAC címeket tartalmazó fáljunk - mac-cimek.txt: | |||
<syntaxhighlight lang="bash"> | |||
00:0C:42:AB:CD:EF | |||
00:0c:42:ab:cd:ef | |||
00-0C-42-AB-CD-EF | |||
00-0c-42-ab-cd-ef | |||
000c42abcdef | |||
000C42ABCDEF | |||
00:0C:42:AB:CD:EF:AB | |||
00:0C:42:AB:CD:EF: | |||
0G:0C:42:AB:CD:EF | |||
00.0C.42.AB.CD.EF | |||
00:0C:42:AB:CD:EG | |||
</syntaxhighlight> | |||
Ebben a fájlban vannak megfelelő és hibás szintaktikájú címek is. A feladat, hogy készítsünk reguláris kifejezést, amely megjeleníti a helyeseket a képernyőn. | |||
<syntaxhighlight lang="bash"> | |||
grep "^\([[:xdigit:]]\{2\}[-:]\?\)\{5\}[[:xdigit:]]\{2\}$" mac-cimek.txt | |||
</syntaxhighlight> | |||
Érdekességképp beletehetünk a fájlba a MAC címek elé és/vagy után véletlenszerű (megjeleníthető) karaktereket. | |||
Mit tapasztalunk? Miért? | |||
Távolítsuk el a sor eleje és a sor vége illesztéseket és futtassuk a grep-et a -o kapcsolóval? Mi változik? | |||
(''grep -o "\('''['''[:xdigit:]''']'''\{2\}[-:]\?\)\{5\}'''['''[:xdigit:]''']'''\{2\}" mac-cimek.txt'') | |||
== 4. óra == | == 4. óra == | ||
A negyedik órán a reguláris kifejezések elkészítését gyakoroljuk különböző példákon keresztül. Főleg scripten belül használjuk. | A negyedik órán a reguláris kifejezések elkészítését gyakoroljuk különböző példákon keresztül. Főleg scripten belül használjuk. | ||
== 5. óra == | == 5. óra == | ||
Az ötödik órán minta ZH feladatsort oldunk meg. | Az ötödik órán minta ZH feladatsort oldunk meg. | ||
A lap jelenlegi, 2024. október 9., 13:15-kori változata
1. óra
Az első óra a tantárgy és annak követelményeinek ismertetésével kezdődik, majd egy-két alap utasítást tekintünk meg. Ezután a programok csatornáival folytatjuk.
Parancsok és példák
man
A man parancs segítségével megtekinthetjük egy-egy alkalmazás, parancs, esetleg külső könyvtár függvényeinek dokumentációját.
Használata: A program neve után írhatjuk, hogy melyik alkalmazás, parancs vagy esetleg külső könyvtár függvényének dokumentációját szeretnénk megtekinteni. Megtekinthetjük ily módon a man parancs használati útmutatóját is a következő utasítás kiadásával:
man man
Hasonló módon alkalmazhatjuk bármelyik parancsra, amelyek ezen a weboldalon felsorolásra kerültek. Pl. a head utasítás dokumentációját az alábbi módon érhetjük el
man head
ls
Érdemes megtekinteni a parancs dokumentációját a man ls utasítás kiadásával, tisztában legyünk ez elérhető kapcsolókkal és funkciókkal.
Az ls parancs segítségével listázhatjuk a mappa tartalmát. Alapértelmezetten a ., tehát a jelenlegi könyvtárat listázza.
# meghívás paraméter nélkül
ls
# meghívás . paraméterrel - ugyanaz az eredmény
ls .
A listázni kívánt könyvtár nevét megadhatjuk paraméterben:
# root könyvtár listázása
ls /
# a /usr/local/bin könyvtár listázása
ls /usr/local/bin
Érdemes megjegyezni a hosszú formátumú kiírást, aminek segítségével a fájlrendszer bejegyzések jogosultságait és méretét kérhetjük le.
# Jelenlegi könyvtárban listáz minden elemet és azok tulajdonságait
ls -l
# A /bin/ls fájl jogosultságainak lekérdezése
ls -l /bin/ls
Próbáljuk ki, hogy ha egy mappa nevével futtatjuk le a parancsot, akkor az ls megnyitja a könyvtárat és annak tartalmát listázza ki.
# a /bin könyvtár tartalma listázódik, nem a /bin könyvtár maga
ls /bin
Ez különösen akkor okoz problémát, ha például az adott könyvtár jogosultságait szeretnénk megtekinteni. Ekkor két választási lehetőségünk adódik:
# A felette lévő könyvtárat listázzuk és kikeressük a megfelelő bejegyzést
ls / -l
# használjuk a -d kapcsolót, aminek segítségével felszólítjuk az ls-t, hogy ne nyissa meg az adott könyvtárat
# Ekkor a könyvtár listázódik, nem a tartalma
ls -d /bin
pwd
A pwd parancs segítségével lekérdezhetjük annak a könyvtárnak az abszolút elérési útvonalát, amelyben éppen benne vagyunk.
A parancsot főleg arra használjuk, hogy aktuálisan mellettünk elhelyezett fájlok és könyvtárak abszolút útvonalát ki tudjuk alakítani.
pwd
cd
A cd parancs segítségével könyvtárat válthatunk (changedir). A cél könyvtár nevét paraméterben kell megadnunk.
# root könyvtár megnyitása
cd /
# HOME könyvtár megnyitása
# ~ egy alias
cd ~
# /usr/bin megnyitása
cd /usr/bin
A hivatkozásoknál, így a cd esetében is lehetőségünk van relatív és abszolút hivatkozásokat használni:
- Az abszolút hivatkozás / elérési út mindig / jellel kezdődik. pl.: cd /home/, cd /usr/bin
- A relatív hivatkozás vagy nem rendelkezik kezdőkarakterrel: cd home, cd bin, vagy . illetve .. karakterekkel kezdődnek.
- A . könyvtár jelenti az aktuális könyvtárat
- A .. könyvtár jelenti a szülő könyvtárat
# szülő könyvtár megnyitása
cd ../
# a szülőkönyvtárban található bin könyvtár megnyitása
cd ../bin
# az aktuális könyvtárban található bin könyvtár megnyitása
cd ./bin
cd bin # vegyük észre: a ./ ez esetben elhagyható
mkdir
Az mkdir parancs segítségével könyvtárakat hozhatunk létre (make directory). Alapértelmezetten a . könyvtáron (tehát ahol éppen tartózkodunk, azon a könyvtáron) belül hozza létre az új mappát, de lehetőségünk van mind relatív, mind abszolút hivatkozások használatára.
# folder könyvtár létrehozása az aktuális könyvtárban
mkdir folder
mkdir ./folder2
# subfolder létrehozása a folder könyvtáron belül.
mkdir folder/subfolder
# létrehozás a /tmp könyvtáron belül, akárhol is vagyunk
mkdir /tmp/folder
# folder létrehozása a szülőkönyvtárban
mkdir ../folder
A fentebb leírtak alapján egyetlen könyvtárat hozhatunk létre, egy már létező könyvtáron belül, legyen az éppen az, amiben tartózkodunk, vagy valahol máshol a fájlrendszerben. Azonban előfordul, hogy egyszerre több mappát szeretnénk elkészíteni, például egy mélyebb struktúrát szeretnénk kialakítani, mint ami a rendelkezésünkre áll. Ezt természetesen megtehetjük úgy, hogy az egyes szinteket egyesével hozzuk létre, de alkalmazhatunk kapcsolót, amelynek segítségével a nem létező szülőkönyvtárakat is létrehozza, amennyiben nem léteznek.
# root könyvtáron belül létrejön egy ''test'' könyvtár és azon belül jön létre a ''folder'' könyvtár.
mkdir /test/folder/ -p
# az aktuális könyvtárban jön létre egy ''test'' könyvtár és azon belül a ''folder'' könyvtár
mkdir -p test/folder
# a jelenlegi könyvtárban létrejon a ''test'' könyvtár,
# azon belül létrejön egy ''folder1'' és egy ''folder2'' könyvtár,
# majd mind a kettőben létrejön a ''work'' könyvtár.
mkdir -p test/{folder1,folder2}/work
Természetesen ahhoz, hogy egy könyvtárban további fájlokat vagy könyvtárakat hozzunk létre jogosultság szükséges.
rmdir
Az rmdir parancs segítségével üres könyvtárakat törölhetünk.
Figyelem! Ha a könyvtár nem üres (fájlok vagy egyéb könyvtárak találhatók benne, akkor hibaüzenetet kapunk és nem csinál semmit!
# relatív hivatkozással
rmdir test/folder
# abszolút hivatkozással
rmdir /test/folder
cp
A cp parancs segítségével fájlokat és könyvtárakat másolhatunk a fájlrendszer egy pontjáról a másikra.
# /etc/passwd fájl lemásolása a jelenlegi könyvtárba - ls paranccsal ellenőrízhető
cp /etc/passwd ./
# /etc/passwd lemásolása a jelenlegi könyvtárba és közben átnevezés file-ra
cp /etc/passwd ./file
# /etc/passwd lemásolása a /tmp könyvtárba
cp /etc/passwd /tmp/
# /etc/passwd lemásolása a /tmp könyvtárba és közben átnevezés file-ra
cp /etc/passwd /tmp/file
Könyvtárak másolása esetén a -r kapcsoló használata szükséges (recursive).
# /etc/network könyvtár és annak tartalmát másolja a /tmp könyvtárba
cp /etc/network /tmp/ -r
mv
Az mv parancs segítségével fájlokat és könyvtárakat mozgathatunk. Ezzel a paranccsal nevezhetjük át a fájlrendszer elemeit.
A próbálkozáshoz másoljuk le a /etc/passwd állományt, ha eddig nem tettük meg!
cp /etc/passwd ./
# passwd állomány átnevezése file-ra
mv passwd file
# nem fut le!
# /etc/passwd állomány átnevezése file-ra
mv /etc/passwd /etc/file
# nem fut le!
# /etc/passwd állomány áthelyezése /tmp-be
mv /etc/passwd /tmp
# nem fut le!
# /etc/passwd állomány áthelyezése /tmp-be és közben átnevezés file-ra
mv /etc/passwd /tmp/file
A könyvtárak áthelyezéséhez (vagy átnevezéséhez) ez esetben nincs szükségünk a recursive (-r) jelölésre.
rm
Az rm parancs segítségével fájlokat és könyvtárakat törölhetünk.
rm file
Könyvtárak törléséhez alkalmaznunk kell a rekurzív jelölést: -r.
rm folder -r
less
A less egy fájlnézegető, amelynek segítségével lapozhatunk billentyűzet segítségével a fájlokban.
less /etc/passwd
more
A more szintén egy fájlnézegető, de ennek segítségével csak előre lapozhatunk, visszafelé nem.
more /etc/passwd
which
A 'which program segítségével lekérdezhetjük, hogy az adott utasításhoz tartozó állomány melyik mappában található.
# az ls parancs abszolút elérési útvonala
which ls
# a which parancs abszolút elérési útvonala
which which
# a man parancs elérési útvonala
which man
file
A file utasítás segítségével lekérdezhetjük, hogy egy adott állomány milyen típusú: futtatható állomány (ELF), ASCII stb.
file /etc/passwd
file /bin/ls
echo
Az echo mindent kiír a képernyőre, amit parancssori argumentumként adunk át neki.
echo "Hello World"
echo Hello World
echo Ez egy teszt üzenet
echo "Ez egy teszt üzenet"
Láthatjuk, hogy idézőjeltől függetlenül minden megjelenik a képernyőn. Észrevehetjük azt is, hogy minden sor végén új sor karakter (enter) található, amit a "-n" kapcsoló segítségével kapcsolhatunk ki.
echo -n "Hello world"
cat
A cat utasítás fájlokat képes összefűzni és az eredményt a képernyőre írja ki.
# /etc/passwd és a /etc/profile fájlok összefűzése a képernyőn (ebben a sorrendben)
cat /etc/passwd /etc/profile
Egy gyakoribb felhasználási módja, hogy a fájlok tartalmát a képernyőre vessük - ez esetben nem fűzünk hozzá semmit a fájlhoz.
# /etc/passwd és a <semmi> összefűzése és megjelenítése a képernyőn
cat /etc/passwd
head
A head utasítás segítségével a fájlok első N során írhatjuk ki a képernyőre. Alapértelmezetten N=10, így ha csak egy fájlnevet adunk neki, akkor annak legfeljebb 10 sorát fogja kiírni (ha van annyi).
head /etc/passwd
Az alapértelmezett N=10 értéket a -n kapcsoló segítségével módosíthatjuk
head -n 5 /etc/passwd
# a -n a dokumentáció elhagyható, ha a - után szám található
head -5 /etc/passwd
tail
A tail hasonlóan működik, mint a head, de ez esetben nem a fájl elejéről ír ki N sort, hanem a végéről.
tail /etc/passwd
Az alapértelmezett N=10 értéket a -n kapcsoló segítségével módosíthatjuk
tail -n 5 /etc/passwd
# a -n a dokumentáció elhagyható, ha a - után szám található
tail -5 /etc/passwd
wc
A wc utasítás segítségével statisztikai adatokat nyerhetünk ki egy fájlból (word counter): sorok, szavak, karakterek és bájtok száma.
wc /etc/passwd
Van lehetőségünk szűkíteni a visszaadott adatokat kapcsolók segítségével:
| Rövid kapcsoló | Hosszú kapcsoló | Leírás |
|---|---|---|
| -l | --lines | sorok számát adja vissza |
| -w | --words | szavak számát adja vissza |
| -c | --chars | karakterek számát adja vissza |
| --bytes | bájtok számát adja vissza |
# sorok számát írja ki
wc -l /etc/passwd
# szavak számát írja ki
wc -w /etc/passwd
# bájtok számát írja ki
wc --bytes /etc/passwd
# sorok és szavak számát írja ki a képernyőre
wc -l -w /etc/passwd
find
A find utasítás segítségével kereshetünk a fájlrendszerben különböző attribútumok alapján.
# passwd nevű fájl keresése a /etc könyvtárban
find /etc -name passwd
Programok csatornái
STDIN
STDOUT
STDERR
Pipeline
Parancsbehelyettesítés
Feladatok
Szedjük ki a /etc/passwd állomány 20. sorát
# beolvassuk az első 20 sort és levágjuk az utolsót
head -20 /etc/passwd | tail -1
Mondjuk meg egy keresett bináris típusát
# fájl elérési út lekérdezése
# STDOUT => /bin/ls
which ls
# fájl típusának lekérdezése
file /bin/ls
# rakjuk össze:
file `which ls`
2. óra
A második órát az alap utasításokkal folytatjuk. Utána scriptek írásával foglalkozunk, amelyben megtekintjük a különböző vezérlési szerkezeteket is.
Parancsok és példák
mcedit
Az mcedit az mc (Midnight Commander) szerkesztője. A Midnight Commander testvére a Total Commander ősének, a Volkov Commandernek, ami szintén egy konzolos alkalmazás. A közös gyökerek miatt nagyon hasonló funkcionalitásokat érhetünk el ebben is, mint a TC-ben - érdemes megnyitni az mc utasítással, amit később az F10 billentyűvel, vagy az alsó sorban arra a gombra kattintással tudunk bezárni. Ebben az alkalmazásban működik az egér is, így kényelmes használatot eredményez. Érdekesség, hogy a "tálcára helyezés" is megoldott, így a Ctrl+O billentyűkombinációkkal háttérbe küldhetjük és folytathatjuk dolgunkat a terminálon, majd ugyanezzel a kombinációval előtérbe is hívhatjuk.
Az mcedit megnyitható az mc-ből is, a szokásos F4-es billentyűvel - vagy az arra való kattintással.
Az egér az mcedit-ben is működik!
A másolás a szerkesztőben is hasonlóan működik, mint a kétpaneles fájltallózóban: F5 és F6 billentyűkkel másolhatunk illetve áthelyezhetünk sorokat. Kilépni az F10 billentyűvel, ESC-el tudunk, de ezt az ablakot is a háttérbe küldhetjük, ha szerkesztés közben terminált szeretnénk elérni (CTRL+O).
mcedit /etc/passwd
nano
A nano szintén egy szövegszerkesztő alkalmazás.
Alul láthatjuk a segédletet, hogy milyen kombinációkkal milyen funkcionalitás érhető el. A szükségesebbek:
- CTRL+K segítségével kivághatunk sorokat a vágólapra (shift+kurzorbillentyűk segítségével tört sorok is kijelölhetők)
- CTRL+U Beilleszti a vágólap tartalmát az aktuális sorba
- CTRL+O Menti a változásokat
- CTRL+X Kilép, de megkérdezi, hogy menteni akarunk-e, ha vannak mentetlen változások
nano /etc/passwd
chmod
shift
cut
A cut parancs segítségével táblázatos adatokat szűrhetünk: kiválaszthatjuk, hogy mely oszlopokat szeretnénk megjeleníteni. A két legfontosabb kapcsolója a -f (field), ahol a megjelenítendő oszlopokat adhatjuk meg és a -d (delimiter), ahol az elválasztó karaktert állíthatjuk be.
Általában a /etc/passwd állományon dolgozunk, mert ebben egy :-al elválasztott táblázat található.
# a fájl első oszlopát szedi ki :-nál elválasztva,
# tehát a felhasználónevet
cut -f1 -d':' /etc/passwd
# a fájl első és harmadik oszlopát adja vissza :-nál elválasztva,
# tehát a felhasználónevet és az id-ját
cut -f1,3 -d':' /etc/passwd
# a fájl első három és hatodik oszlopát adja vissza :-nál elválasztva,
# tehát a felhasználónevet, jelszót és a felhasználó id-ját, valamint a home könyvtárát
cut -f1-3,6 -d':' /etc/passwd
sort
A sort utasítás segítségével rendezhetjük az adattömböt.
# a passwd állomány rendezése a felhasználónév szerint - ez van elől
sort /etc/passwd
# fordított sorrend - reverse
sort -r /etc/passwd
Alapértelmezetten karakterek szerint rendez, tehát a számokat tartalmazó adatsorokat nem helyes sorrendben adja vissza. Ha számérték szerinti rendezést szeretnénk végrehajtani, akkor használjuk a -n opciót.
# file egy számokat tartalmazó fájl - egy sor egy fájl
sort -n file
# fordított sorrend
sort -r -n file
tr
A tr parancs segítségével karaktereket cserélhetünk ki egy fájlban. Ezen kívül nagyon hasznos tulajdonsága, hogy a kívánt ismétlődéseket el tudja távolítani, mintegy megtisztítva az adatsort.
# az e betűt o-ra, az o betűt e-re cseréli ki
echo "hello" | tr eo oe
# A T betűt K-ra, az n betűt p-re cseréli ki
echo "Tanar" | tr Tn Kp
A fenti példák alapján nézzük meg, hogy mi történik:
- A tr két pozicionális paraméterrel lett meghívva
- Az első paraméter adja meg a lecserélendő karakterek halmazát
- A második paraméter adja meg az új karakterek halmazát
- A program végig megy a bemeneten és közben megvizsgálja, hogy az adott karakter megtalálható-e az első paraméterben
- ha megtalálható, akkor lecseréli a karakterrel azonos pozícióban álló második paraméterben található értékre
- ha nincs benne, akkor megy tovább
- a metodika miatt keresztbe is lehet cserélni (pl. o-t e-re, e-t o-ra, mint az első példában). Gondoljuk végig, hogy ha nem így lenne, akkor az először lecserélt e betűnek a végén o betűre kéne cserélődnie.
if
Az if segítségével elágazásokat hozhatunk létre, mint minden más programozási nyelven. A szerkezet a következőképp néz ki:
if KIFEJEZÉS
then
elif KIFEJEZÉS
elif KIFEJEZÉS
else
fi
Természetesen az egyes feltételek kihagyhatók, így készíthetünk egy egyszerű if elágazást is:
if KIFEJEZÉS
then
fi
Ha egy sorban szeretnénk leírni (nem scriptben), akkor a következőképpen tehetjük meg:
if KIFEJEZÉS; then UTASÍTÁS1; UTASÍTÁS2; elif KIFEJEZÉS; then UTASÍTÁS1; UTASÍTÁS2; else UTASÍTÁS; fi
KIFEJEZÉS
Egy olyan program, amelynek a visszatérési értéke hasznos információkat hordoz a futás eredményét tekintve. Ne feledjük el, hogy a return kulcsszóval tudunk ilyen értéket generálni C/C++ kódok esetében. Lássunk egy példát:
#include <stdio.h>
int main() {
if ( 10 % 2 == 0 ) return 0;
else return 1;
}
A fenti program visszatérési értéke információval szolgál számunkra, hogy a 10 osztható-e kettővel, avagy sem. Ez az érték vizsgálható az if segítségével és a válasz függvényében más-más kódokat hajthatunk végre.
A kiértékelés ellentétes a megszokott módszerhez képest (ahol minden igaz, aminek az értéke nem 0).
# ha a KIFEJEZÉS 0 értéket ad vissza, akkor IGAZ az állítás, tehát az if-en belüli kód fut
if KIFEJEZÉS => 0
then
....
else
....
fi
# ha a KIFEJEZÉS nem 0 értéket ad vissza, akkor HAMIS az állítás, tehát az else-n belüli kód fut
if KIFEJEZÉS => != 0
then
...
else
...
fi
A programozási nyelvek tanításakor ezért térünk vissza 0-s értékkel (return 0;), a programunk végén, és hiba esetén 1, vagy annál nagyobb értékkel.
test
A test parancs logikai függvényeket értékel ki és
- 0 értéket ad vissza, ha az eredmény IGAZ,
- 1 értéket ad vissza, ha az eredmény HAMIS
Az if utasítással együtt szoktuk használni, de természetesen ettől független is meghívható.
# megtörténik a logikai kiértékelés, eldől, hogy a két string egyezik-e
test "text1" == "text2"
# kiírjuk a képernyőre a test utasítás visszatérési értékét
echo $?
if utasítással a következőképp használhatjuk:
# hamis
if test "text1" == "text2"
then
echo "igaz"
else
echo "hamis"
fi
# igaz
if ! test "text1" == "text2"
then
echo "igaz"
else
echo "hamis"
fi
#igaz
if test "text1" != "text2"
then
echo "igaz"
else
echo "hamis"
fi
Elérhető egy alias, aminek segítségével olvashatóbbá tehetjük a test utasítást. Ez a [ ] pár.
if [ "text1" == "text2" ]
then
echo "igaz"
else
echo "hamis"
fi
Ügyeljünk rá, hogy a [ és a ] zárójelek mellett whitespace karakterek vannak. Ha ezeket kihagyjuk, akkor hibát fogunk kapni!
A számok ellenőrzése BASH környezetben körülményesebb, mivel itt minden karakterláncnak számít. Emiatt a következő utasítás sorozat nem várt eredménnyel zárul:
if [ "1000" <= "20" ]
then
echo "igaz"
else
echo "hamis"
fi
Az eredmény: igaz. De tudjuk, hogy ez az eredmény nem igaz, a BASH mégis így értékelte ki. Az oka, hogy az első karaktereket tekintve (1 és 2) elmondható, hogy az 1-es hamarabb van az ABC-ben (kódtáblában), mint a 2, így az 1000-nek kisebbnek kell lennie (mintha a "alma" és "körte" lenne összehasonlítva, hogy melyik következik előbb az ABC-ben).
Ahhoz, hogy a test utasítás karakterek helyett számként dolgozza fel a paramétert, kapcsolót kell használnunk:
| Kapcsoló | Angol megnevezés | Magyar megnevezés |
|---|---|---|
| -eq | Equals | Egyenlő |
| -ne | Not Equals | Nem egyenlő |
| -lt | Lower than | Kisebb, mint |
| -le | Lower than or equals | Kisebb vagy egyenlő |
| -gt | Greather than | nagyobb, mint |
| -ge | Greather than or equals | Nagyobb vagy egyenlő |
if [ 1000 -le 20 ]
then
echo "igaz"
else
echo "hamis"
fi
Az eredmény: Az elvártaknak megfelelően HAMIS.
for
A for utasítás segítségével egy lista elemein mehetünk végig. Hasonlóan működik, mint a modern programozási nyelvekben a foreach.
Legegyszerűbben a következő utasítással tesztelhetjük, ahol a bemeneti listát soronként látjuk viszont a képernyőn:
for i in 1 2 3 4 5 6
do
echo $i
done
Természetesen van lehetőségünk a listát más program kimenetéből kinyerni a parancsbehelyettesítés segítségével:
for i in `ls`
do
echo $i
done
A for gyakorlatilag a pozicionális paramétereken megy végig, tehát egy lista elem a $1, egy másik listaelem a $2. Tudjuk, hogy ha szóközök között adjuk meg, akkor szóközt is tartalmazhat a paraméterünk. Lássunk egy példát:
for i in "1 2 3" "4 5 6"
do
echo $i
done
Ez esetben a képernyőn két sor jelenik meg: 1 2 3 és 4 5 6. Azonban a parancsbehelyettesítés nem alkalmaz az idézőjelhez hasonló technikát, tehát azt alkalmazva minden szó (szóközökkel határolt karaktersorozat) új pozicionális paramétert jelent. Lássunk egy az előzőhöz hasonló példát:
for i in `echo "1 2 3 4 5 6"`
do
echo $i
done
Ez esetben hat sor jelenik meg, benne egy-egy számmal, tehát az echo "1 2 3 4 5 6" kimenetét szóközönként vágta fel.
while
A while utasítás, mint minden programozási nyelvben, itt is felfogható úgy, mint egy többször lefutó if. Éppen ezért a szintaktikájuk megegyezik, csupán a feltételek megírásával kell óvatosan bánnunk, hogy a ciklus mag akkor és addig fusson, ameddig mi azt szeretnénk. A while ciklusnál ugyanazokat az alkalmazásokat írhatjuk be a KIFEJEZÉS helyére, mint az if esetében.
while KIFEJEZÉS
do
done
Például ha azt akarjuk, hogy egy ciklus addig fusson, amíg meg nem jelenik egy fájl a fájlrendszerben, akkor azt a következőképp vezethetjük le:
# ellenőrzi, hogy a fájl elérhető-e
test -f "file.txt"
# ez esetben egyetlen kísérletet teszünk, de nem várjuk meg, hogy oda kerüljön, amennyiben nincs ott
if test -f "file.txt"
then
echo "a fájl létezik"
else
echo "A fájl nem létezik"
fi
# várakozunk, amíg a feltétel nem lesz igaz, tehát a fájl nem kerül oda
while ! test -f "file.txt"
do
echo "várakozunk"
done
echo "a fájl létezik"
# test parancs helyettesítése []-el
while ! [ -f "file.txt" ]
do
echo "várakozás"
done
echo "a fájl létezik"
A while ciklusnál érdemes megemlíteni a until utasítást, ami annyiban tér el, hogy a feltétel kiértékelését invertálni kell - tehát ami igaz a while esetében, az hamis az until esetében és fordítva. Így a fenti feladatot megvalósíthatjuk invertálás nélkül, az until utasítással is:
until test -f "file.txt"
do
echo "várakozás"
done
echo "a fájl létezik"
seq
A seq utasítás egy listát generál számunkra, amelyben a megadott lépésszámmal, a megadott legkisebb értéktől a megadott legnagyobb értékig szerepelnek a számok.
# számok 1-10-ig
seq 10
# számok 5-10-ig
seq 5 10
# számok 3-tól 10-ig 2-esével
seq 3 2 10
A seq utasítást általában a for ciklus listájában használjuk, hogy elő tudjuk állítani az indexeket.
for i in `seq 3 2 10`
do
echo $i
done
read
A read utasítás segítségével a STDIN-ről kérhetünk be információt változóba/változókba. Ha több változót sorolunk fel, akkor a bemenetet szóközöknél vágja el.
# beolvasás var-ba
# STDIN => teszt
# var => teszt
# STDIN => teszt szöveg
# var => teszt szöveg
read var
# beolvasás fname és lname változókba
# STDIN => Attila Farkas
# fname => Attila
# lname = Farkas
# STDIN => Attila
# fname => Attila
# lname => <üres>
# STDIN => Attila Farkas OPSYS
# fname => Attila
# lname => Farkas OPSYS
read fname lname
# beolvasás három változóba. Ha a felhasználó az utasításokkal szemben több szót adott meg, akkor így biztosíthatjuk, hogy ne legyen szóköz az első két változóban
# STDIN => Attila Farkas
# fname => Attila
# lname => Farkas
# tmp => <üres>
# STDIN => Attila Farkas OPSYS meg valami más
# fname => Attila
# lname => Farkas
# tmp => OPSYS meg valami más
read fname lname tmp
Az utóbbi esetben hibaüzenet is generálható, ha megvizsgáljuk, hogy a tmp változó értéke üres-e:
echo -n "Adja meg a teljes nevét: "
read fname lname tmp
# -n => nem üres?
# -z => üres?
if [ -n "$tmp" ]
then
echo "Valamit elhibáztál"
exit 1
fi
Ha szeretnénk ellenőrzött bekérést végrehajtani:
tmp="start value"
while [ -n "$tmp" ]
do
echo -n "Adja meg a teljes nevét FNAME LNAME formátumban: "
read fname lname tmp
if [ -n "$tmp" ]
then
echo "Valamit elrontottál!"
# ez esetben nem lépünk ki, mert bekérjük újra
fi
done
expr
Az expr parancs segítségével tudunk matematikai műveleteket végrehajtani. Mivel a BASH-ben minden változó karakterlánc, így nem tudunk közöttük műveletet végezni. Az expr a paramétereket belül számként kezeli. Csak egész számokkal tud dolgozni!
# a képernyőre kerül az eredmény
expr 1 + 2
expr 4 * 4
# csak egész számot ír ki
expr 3 / 2
Ha tört számokkal kell dolgoznunk, akkor a következőket tehetjük:
- eltávolítjuk a törtrészt
- felszorozzuk 10^n-nel, ahol n a törtrész számjegyeivel egyezik meg (pl. 10.02-t 100-al kell szorozni). Az egész térben elvégzett művelet eredményét később vissza osztjuk ugyanannyival, amennyivel korábban felszoroztuk. Ez nem egy egyszerű feladat, hiszen a tört számot egyáltalán nem kezeli az expr, tehát cut, wc és egyéb parancsokkal kell kialakítanunk a számot, ahogy utána szét is kell darabolnunk azt.
- Másik környezetet használunk, ahol tudunk számokat is kezelni - ez a ZH-n nem elfogadott
A lehetőségek közül csak az elsőt, a ZH-n teljes mértékben elfogadott megoldást mutatom be:
# a 3.4-et és a 1.2-őt kell összeadnunk.
# ennek eredménye 3
echo "3.4" | cut -d'.' -f1
# ennek eredménye 1
echo "1.2" | cut -d'.' -f1
# rakjuk össze
expr `echo "3.4" | cut -d'.' -f1` + `echo "1.2" | cut -d'.' -f1`
Feladatok parancsokhoz
Írassuk ki a /etc/passwd több sorát
Több választási lehetőségünk van:
- ha a kiírandó sorszámok valamilyen logikát követnek (minden második, harmadik stb.), akkor használhatjuk a seq utasítást
- ha nincs logika a sorszámokban, akkor kézzel kell elkészítenünk a listát
Logikát tartalmazó sorszámok
Írassuk ki minden harmadik sor tartalmát
# határozzuk meg a seq tartományát
# min: 1
# max: ahány sora van a fájlnak
# max érték meghatározás
# a változó létrehozást lentebb tárgyaljuk
max=`cat /etc/passwd | wc -l`
# lista meghatározása for ciklushoz
# 1-től $max-ig hármasával
seq 1 3 $max
# Rakjuk össze
for i in `seq 1 3 $max`
do
head -$i /etc/passwd | tail -1
done
Logikát nem tartalmazó sorszámok
Írassuk ki a 2., 5., 10. és 11. sorokat
for i in `2 5 10 11`
do
head -$i /etc/passwd | tail -1
done
Fájlok ellenőrzése és másolása
Másoljuk át a /etc/passwd állományt egy könyvtárba (~/test/destination). Ha a célkönyvtár nem létezik, akkor hozzuk létre. Ha a célkönyvtár és a fájl is létezik, akkor írjunk ki hibaüzenetet.
# forrás fájl létezésének vizsgálata
test -f /etc/passwd
# célfájl létezésének vizsgálata
test -f ~/test/destination/passwd
# mappa létezésének vizsgálata
test -d ~/test/destination
# rakjuk össze
# ha a forrásfájl nem létezik
if ! test -f /etc/passwd
then
echo "A forrásfájl nem létezik"
# ha a célfájl létezik
elif test -f ~/test/destination/passwd
then
echo "A fájl már létezik"
# ha a cél mappa nem létezik
elif ! test -d ~/test/destination
then
# mappa létrehozás - szülőkönyvtárakat is, ha nem léteznek
mkdir -p ~/test/destination
# fájl belemásolása
cp /etc/passwd ~/test/destination
# ha a célfájl nem létezik, de a célmappa igen
else
# a fájlt bemásoljuk a könyvtárba
cp /etc/passwd ~/test/destination
fi
Script létrehozása
- Script megírása
- Futási jog
Pozicionális paraméterek
Változók
3. óra
A harmadik órán reguláris nyelvekkel foglalkozunk. A nyelv szintaktikai elemzése után a BASH-ben erre alkalmas szoftvert, a grep-et foguk megvizsgálni.
Reguláris kifejezés szerkezete
A reguláris nyelvek atomokból, lezártakból épül fel, amelynek az eredménye az úgynevezett „összetettek”.
Atomok
Az atomok egy karakterre illeszkednek a sorban.
| Atom | jelentés |
|---|---|
| betűk, számok | saját magukra illeszkednek |
| ^ | sor elejére illeszkedik (csak egyszer lehet a legelején) |
| $ | sor végére illeszkedik (csak egyszer lehet a legvégén) |
| [abc] | halmaz: minden benne lévő elemre illeszkedik |
| [^abc] | inverz halmaz: egyetlen benne lévő elemre sem illeszkedik |
| . | mindenre illeszkedik |
Lezártak
A lezártak ismétlődéseket fogalmaznak meg egy atomra vonatkozóan. Lezárt csak atom után helyezkedhet el!
| Lezárt | jelentés |
|---|---|
| * | az atomot 0 és végtelen között akárhányszor ismételheti |
| + | az atomot 1 és végtelen között akárhányszor ismételheti |
| ? | az atomot 0 és 1 között akárhányszor ismételheti |
| {n} | az atom pontosan n-szer fordul elő egymás mellett |
| {n,m} | az atomot n és m között akárhányszor ismételheti |
| {n,} | az atomot n és végtelen között akárhányszor ismételheti |
| {,m} | az atomot 0 és m között akárhányszor ismételheti |
Összefűzöttek
Az atomok és a lezártak egymás után írt sorozata.
A lezártaknál fontos kitétel volt, hogy csak atom után lehet írni. Egy összefűzött újra atomizálható a ( ) karakterekkel. Az összefűzöttek tartalmazhatnak uniót (|), ahol több szabály közül bármelyik megvalósulhat egy sikeres illesztéshez.
Parancsok és példák
Ez egy teszt szöveg, amin próbálkozunk.
A fenti szöveget alapul véve, a következő reguláris kifejezéseket hozhatjuk létre:
| Reguláris kifejezés | Illeszkedik? | Magyarázat |
|---|---|---|
| E | Igen | Van a sorban E betű |
| a | Igen | Van a sorban a betű |
| b | Nem | Nincs a sorban b betű |
| ^E | Igen | A sor elején van az E betű |
| ^A | Nem | Nincs a sor elején A betű |
| ^e | Nem | nincs a sor elején e betű |
| .$ | Igen | Bármilyen karakter lehet a sor végén |
| \. | Igen | . van a sor végén |
| k$ | Nem | Nincs k a sor végén |
| egy | igen | Van a sorban „egy” string |
| egység | Nem | Nincs a sorban egység string |
| egy* | Igen | eg kötelező, y 0 vagy végtelenszer lehet (egy, egyy, egyyy, egyyyy ...) |
| l*egy | Igen | l 0 vagy végtelen, eg kötelező (eg, leg, lleg, llleg, lllleg ...) |
| l+egy | Nem | Nincs a szövegben "l+egy" string |
| l\+egy | Nem | l 1 vagy végtelen hosszú, egy kötelező (legy, llegy, lllegy, llllegy ...) |
| (egy) | Nem | Nincs a sorban "(egy)" string |
| \(egy\) | Igen | Van a sorban "egy" string |
| \(egy\)* | Igen | Van a sorban legalább 0-szor "egy" string |
| \(egy\)\+ | Igen | Van a sorban legalább 1-szer "egy" string |
| \(egy\)\{2\} | Nem | Nincs a sorban pontosan kétszer "egy" string |
| [a-z] | Igen | Vannak benne kisbetűk |
| [A-Z] | Igen | Van benne nagy betű |
| ^[A-D] | Nem | Nincs a sor elején A-D tartományban betű |
| ^[A-Z] | Igen | Nagy betű van a sor elején |
| ^[A-Z].*\.$ | Igen | Nagybetűvel kezdőik, középen bármi lehet és ponttal végződik a sor. |
| [0-9] | Nem | Nincs számjegy a sorban |
| .* | Igen | Mindenre illeszkedik, bármilyen hosszan (üres sorra is) |
| ^$ | Nem | Csak az üres sorra illeszkedik |
| ^.\+$ | Igen | Mindenre illeszkedik, kivéve az üres sorra |
A következő kifejezés szintén illeszkedik:
^[A-Z].*\(egy\)\|\(kettő\).*\.$ => A sor elején nagybetűvel kezdődik, van a közepén valahol benne "egy" vagy "kettő" karakterlánc és ponttal végződik. A köztes karakterek értéke nincs megszabva.
grep
A grep utasítás segítségével végezhetünk el reguláris kifejezés, tehát minta illesztést fájlokon. Amennyiben nem adunk meg fájl paramétert, a STDIN csatornát olvassa. Az eredmények a STDOUT-ra íródnak.
| Rövid név | Hosszú név | Magyarázat |
|---|---|---|
| -c | --count | Megszámolja az illeszkedő sorokat |
| -o | --only-matching | Csak a mintára illeszkedő részt írja ki (nem a teljes sort) |
| -n | --line-number | Megszámozza a sorokat (a fájl alapján, nem a megjelenítés szerint) |
Példa
# nologin környezetet futtató felhasználók listája a rendszerben
grep "nologin" /etc/passwd
cat /etc/passwd | grep "nologin" # STDIN-en érkező adatok szűrése
# bash környezetet futtató felhasználók listája a rendszerben
grep "bash" /etc/passwd
cat /etc/passwd | grep "bash" # STDIN-en érkező adatok szűrése
Példa 2
Írjunk egy scriptet, amely a /bin/bash futtatási környezetet kapó felhasználók nevét kiírja a képernyőre.
#!/bin/bash
# a fájl, amin dolgozunk
file="/etc/passwd"
# a fájl sorainak száma
lines=`cat $file | wc -l`
# végig megyünk a fájl sorain
for i in `seq 1 $lines`; do
# itt kapjuk meg az i. sort
line=`head -$i $file | tail -1`
# kiszedjük a shell környezetet
shell=`echo $line | cut -f7 -d':'`
# ha ez "/bin/bash", akkor kivágjuk a sor első oszlopát, ezt írhatjuk a képernyőre
if test $shell == "/bin/bash"; then
echo $line | cut -f1 -d':'
fi
done
A fenti script futási ideje: 0.227s
#!/bin/bash
# a fájl, amin dolgozunk
file="/etc/passwd"
# szűrjük ki a sorokat, amelyeknek a végén a "/bin/bash" karakterlánc található
# és a kapott eredményhalmaznak vágjuk ki az első oszlopát
# a kapott eredményhalmaz még mindig megfelel a /etc/passwd eredeti formátumának,
# csak a sorok számát csökkentettük a szűrési feltételnek megfelelően!
grep "/bin/bash$" $file | cut -f1 -d':'
A fenti script futási ideje: 0.003s
MAC cím parser
Legyen egy MAC címeket tartalmazó fáljunk - mac-cimek.txt:
00:0C:42:AB:CD:EF
00:0c:42:ab:cd:ef
00-0C-42-AB-CD-EF
00-0c-42-ab-cd-ef
000c42abcdef
000C42ABCDEF
00:0C:42:AB:CD:EF:AB
00:0C:42:AB:CD:EF:
0G:0C:42:AB:CD:EF
00.0C.42.AB.CD.EF
00:0C:42:AB:CD:EG
Ebben a fájlban vannak megfelelő és hibás szintaktikájú címek is. A feladat, hogy készítsünk reguláris kifejezést, amely megjeleníti a helyeseket a képernyőn.
grep "^\([[:xdigit:]]\{2\}[-:]\?\)\{5\}[[:xdigit:]]\{2\}$" mac-cimek.txt
Érdekességképp beletehetünk a fájlba a MAC címek elé és/vagy után véletlenszerű (megjeleníthető) karaktereket. Mit tapasztalunk? Miért?
Távolítsuk el a sor eleje és a sor vége illesztéseket és futtassuk a grep-et a -o kapcsolóval? Mi változik?
(grep -o "\([[:xdigit:]]\{2\}[-:]\?\)\{5\}[[:xdigit:]]\{2\}" mac-cimek.txt)
4. óra
A negyedik órán a reguláris kifejezések elkészítését gyakoroljuk különböző példákon keresztül. Főleg scripten belül használjuk.
5. óra
Az ötödik órán minta ZH feladatsort oldunk meg.