Az Ubuntu és általában a Linux disztribúciókkal való munka elsajátításának fontos része a shell környezetben való munka elsajátítása. Bár a Linuxhoz mellékelt grafikus asztali környezetek, mint például a GNOME, felhasználóbarát felületet biztosítanak az operációs rendszerhez, a gyakorlatban a shell környezet sokkal nagyobb lehetőségeket, rugalmasságot és automatizálást biztosít, mint amit a grafikus asztali eszközökkel valaha is el lehet érni. A shell-környezet az operációs rendszerrel való interakcióra is lehetőséget nyújt, amikor az asztali környezet nem áll rendelkezésre; ez gyakran előfordul, amikor szerver-alapú operációs rendszerrel, például Ubuntuval vagy olyan sérült rendszerrel dolgozunk, amely nem bootol teljesen.
Ez a fejezet célja tehát, hogy áttekintést adjon az Ubuntu alapértelmezett shell-környezetéről (konkrétan a Bash shell-ről).
1.1 Mi a shell?
A shell egy interaktív parancsértelmező környezet, amelyen belül parancsokat lehet beírni egy promptra vagy szkript formájában beírni egy fájlba és végrehajtani. A héj eredete a UNIX operációs rendszer korai napjaira vezethető vissza. Valójában a Linux korai napjaiban, a grafikus asztalok bevezetése előtt a shell volt az egyetlen módja annak, hogy a felhasználó kapcsolatba lépjen az operációs rendszerrel.
Az évek során számos shell környezetet fejlesztettek ki. Az első széles körben használt héj a Bourne héj volt, amelyet Stephen Bourne írt a Bell Labs-nél.
Egy másik korai alkotás a C héj volt, amely szintaxisában hasonlított a C programozási nyelvhez, és olyan használhatósági fejlesztéseket vezetett be, mint a parancssori szerkesztés és az előzmények.
A Korn shell (amelyet David Korn fejlesztett ki a Bell Labs-nél) a Bourne shell és a C shell által nyújtott szolgáltatásokon alapul.
Az Ubuntu alapértelmezett shellje a Bash shell (a Bourne Again SHell rövidítése). Ezt a héjat, amely a Bourne héj nyílt forráskódú változataként kezdte életét, Brian Fox fejlesztette ki a GNU projekt számára, és mind a Bourne héj, mind a C héj által biztosított tulajdonságokon alapul.
1.2 A héjhoz való hozzáférés
A GNOME asztali környezetből a héj promptja egy Terminál ablakból érhető el a felső sávban a Tevékenységek opció kiválasztásával, a keresősávba a Terminál beírásával és a Terminál ikonra kattintással.
Az Ubuntu szerverre való távoli bejelentkezéskor, például SSH használatával, a felhasználónak szintén megjelenik egy héj prompt. A távoli szerver SSH használatával történő elérésének részleteiről az “SSH kulcs alapú hitelesítés konfigurálása Ubuntun” című fejezetben olvashat. Olyan kiszolgáló alapú rendszer indításakor, amelyre nem telepítettek asztali környezetet, a héjba közvetlenül azután lépünk be, hogy a felhasználó befejezte a bejelentkezési eljárást a fizikai konzolterminálon vagy a távoli bejelentkezési munkamenetben.
1.3 Parancsok bevitele a parancssorba
A parancsok bevitele a héj parancssorba egyszerűen a parancs beírásával és az Enter billentyű lenyomásával történik. Míg egyes parancsok némán hajtanak végre feladatokat, a legtöbb parancs megjelenít valamilyen kimenetet, mielőtt visszatérne a parancssorba. Az ls parancs például az aktuális munkakönyvtárban lévő fájlok és könyvtárak megjelenítésére használható:
$ ls
Asztali dokumentumok Letöltések Zene Képek Nyilvános sablonok Videók
A rendelkezésre álló parancsok vagy magába a shellbe vannak beépítve, vagy a fizikai fájlrendszerben találhatók. Egy parancs fájlrendszeren belüli helye a which paranccsal azonosítható. Például, hogy megtudjuk, hol található az ls futtatható parancs a fájlrendszeren:
$ which ls alias ls='ls --color=auto' /usr/bin/ls
Az ls parancs nyilvánvalóan a /usr/bin könyvtárban található. Figyeljük meg azt is, hogy egy alias is be van állítva, amely témát a fejezet későbbi részében tárgyaljuk. Ha a which parancsot használjuk a héjba épített parancsok elérési útvonalának megkeresésére, akkor egy olyan üzenetet kapunk, amely azt jelzi, hogy a futtathatót nem találjuk. Ha például a history parancs (amely valójában a héjba van beépítve, nem pedig futtatható állományként létezik a fájlrendszerben) helyét próbáljuk megkeresni, a következőhöz hasonló kimenetet kapunk:
$ which history/usr/bin/which: no history in (/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)
1.4 Információszerzés egy parancsról
A Linux héjban elérhető parancsok közül sok kezdetben rejtélyesnek tűnhet. Ha részletes információkat szeretne megtudni arról, hogy mit csinál egy parancs, és hogyan kell használni, használja a man parancsot a parancs nevét argumentumként megadva. Ha például többet szeretne megtudni a pwd parancsról:
$ man pwd
A fenti parancs végrehajtásakor megjelenik a pwd parancs részletes leírása. Számos parancs további információkat is szolgáltat, ha a -help parancssori opcióval futtatjuk:
$ wc --help
1.5 Bash parancssori szerkesztés
A korai shell környezetek nem biztosítottak semmilyen formában sorszerkesztési lehetőséget. Ez azt jelentette, hogy ha hibát vett észre egy hosszú parancssor elején, amit beírt, törölnie kellett az összes következő karaktert, kijavítani a hibát, majd újra beírni a parancs hátralévő részét. Szerencsére a Bash a parancssor-szerkesztési lehetőségek széles skáláját kínálja, amint azt a következő táblázatban bemutattuk:
Billentyűsorozat | Művelet |
Ctrl-b vagy Balra nyíl | A kurzor egy pozícióval hátrébb mozgatása |
Ctrl-f vagy Jobb nyíl | A kurzor egy pozíciót előre |
Törlés | Az aktuális karakter törlése. a kurzor alatt |
Backspace | A kurzortól balra lévő karakter törlése |
Ctrl-_ | Előző módosítás visszavonása (megismételhető az összes korábbi módosítás visszavonásához) |
Ctrl-a | Mozdítja a kurzort a sor elejére |
Ctrl-e | Mozdítja a kurzort a sor végére |
Meta-f vagy Esc majd f | Mozdítja a kurzort egy szóval előre |
Meta-b vagy Esc majd b | Mozdítja a kurzort egy szóval hátra |
Ctrl-l | Képernyő törlése az aktuális parancs kivételével |
Ctrl-k | Törlés a sor végére az aktuális kurzor pozíciójától |
Meta-d vagy Esc majd d | Törlés az aktuális szó végére |
Meta-DEL vagy Esc majd DEL | Törlés az aktuális szó elejére |
Ctrl-w | Törlés az aktuális kurzorpozíciótól az előző szóközig |
Táblázat 9-1
1.6 Munka a Shell előzményekkel
A parancssori szerkesztési funkciók mellett a Bash shell parancssori előzmények támogatását is biztosítja. A korábban végrehajtott parancsok listája megtekinthető a history paranccsal:
$ history1ps2ls3ls –l /4ls5man pwd6man apropos
A Ctrl-p (vagy felfelé mutató nyíl) és a Ctrl-n (vagy lefelé mutató nyíl) billentyűkkel ezen kívül előre és hátra lehet lapozni a korábban beírt parancsok között. Amikor megjelenik a kívánt parancs az előzmények közül, nyomja meg az Enter billentyűt a parancs végrehajtásához.
Egy másik lehetőség a ‘!’ karakter beírása, amelyet az ismétlendő parancs első néhány karaktere követ, majd az Enter billentyű.
1.7 Filename Shorthand
Néhány shell parancs egy vagy több fájlnevet vesz fel argumentumként. Például egy list.txt nevű szöveges fájl tartalmának megjelenítéséhez a cat parancsot a következőképpen használhatjuk:
$ cat list.txt
Hasonlóképpen, több szöveges fájl tartalma is megjeleníthető az összes fájl nevének argumentumként való megadásával:
$ cat list.txt list2.txt list3.txt list4.txt
Ahelyett, hogy minden egyes nevet beírnánk, a mintaillesztés segítségével megadhatjuk az összes olyan fájlt, amelynek neve megfelel bizonyos kritériumoknak. Például a ‘*’ joker karakterrel egyszerűsíthető a fenti példa:
$ cat *.txt
A fenti parancs az összes .txt kiterjesztésű fájl tartalmát megjeleníti. Ezt tovább lehet szűkíteni a listával kezdődő és .txt végződésű fájlnevekre:
$ cat list*.txt
A ‘?’ karakter használatával egykarakteres találatok is megadhatók:
$ cat list?.txt
1.8. A fájlnév és az útvonal kitöltése
A teljes fájlnév vagy útvonal beírása helyett, vagy a gépelés mennyiségét csökkentő mintaillesztés használata helyett a shell biztosítja a fájlnév kitöltés funkciót. A fájlnév-kiegészítés használatához egyszerűen írja be a fájl vagy az elérési útvonal nevének első néhány karakterét, majd nyomja le kétszer az Esc billentyűt. A parancsértelmező ezután kiegészíti a fájlnevet a könyvtárban található első olyan fájl- vagy elérési útvonalnévvel, amely megfelel a beírt karaktereknek. A lehetséges egyezések listájának megtekintéséhez nyomja le az Esc = billentyűt az első néhány karakter beírása után.
1.9 Bemenet és kimenet átirányítása
Amint korábban említettük, számos héjparancs végrehajtásakor információt ad ki. Alapértelmezés szerint ez a kimenet egy stdout nevű eszközfájlba kerül, amely lényegében a terminálablak vagy konzol, amelyben a shell fut. Ezzel szemben a shell a bemenetet az stdin nevű eszközfájlból veszi, ami alapértelmezés szerint a billentyűzet.
A parancsok kimenete átirányítható az stdout-ból egy fizikai fájlba az állományrendszerben a ‘>’ karakter használatával. Például az ls parancs kimenetének egy files.txt nevű fájlba történő átirányításához a következő parancsra van szükség:
$ ls *.txt > files.txt
A files.txt parancs befejezésekor az aktuális könyvtárban lévő fájlok listáját tartalmazza. Hasonlóképpen egy fájl tartalma is betáplálható egy parancsba az stdin helyett. Például egy fájl tartalmának átirányítása egy parancs bemeneteként:
$ wc –l < files.txt
A fenti parancs megjeleníti a files.txt fájlban található sorok számát.
Fontos megjegyezni, hogy a ‘>’ átirányítási operátor használata esetén új fájlt hoz létre, vagy egy meglévő fájlt csonkol. Egy meglévő fájlhoz való csatoláshoz használja a ‘>>’ operátort:
$ ls *.dat >> files.txt
A standard kimeneten kívül a shell a standard hibakimenetet is biztosítja az stderr segítségével. Míg egy parancs kimenete az stdout-ra, addig a parancs által generált hibaüzenetek az stderr-re kerülnek. Ez azt jelenti, hogy ha az stdout egy fájlba van irányítva, a hibaüzenetek akkor is megjelennek a terminálban. Általában ez a kívánt viselkedés, bár az stderr is átirányítható, ha szükséges, a ‘2>’ operátor segítségével:
$ ls dkjfnvkjdnf 2> errormsg
A parancs befejezésekor az errormsg fájlban egy hibaüzenet jelenik meg, amely arról számol be, hogy a dkjfnvkjdnf nevű fájl nem található.
Az stderr és az stdout is átirányítható ugyanabba a fájlba a &> operátor segítségével:
$ ls /etc dkjfnvkjdnf &> alloutput
A végrehajtás befejezésekor az alloutput fájl tartalmazza mind a /etc könyvtár tartalmának listáját, mind a nem létező fájl listázására tett kísérlethez kapcsolódó hibaüzenetet.
1.10 Munka csővezetékekkel a Bash Shellben
A shell az I/O átirányítás mellett azt is lehetővé teszi, hogy egy parancs kimenete közvetlenül egy másik parancs bemeneteként kerüljön csővezetékbe. A pipe művelet úgy érhető el, hogy a parancssoron két vagy több parancs közé a ‘|’ karaktert helyezzük. Például a rendszerben futó folyamatok számának megszámlálásához a ps parancs kimenete átvezethető a wc parancsba:
$ ps –ef | wc –l
A parancssoron végrehajtható pipaműveletek száma nem korlátozott. Például egy fájlban a Smith nevet tartalmazó sorok számának megállapításához:
$ cat namesfile | grep Smith | wc –l
1.11 Aliasok beállítása
Amint egyre jobban elsajátítja a shell környezetet, valószínű, hogy gyakran fog parancsokat kiadni ugyanazokkal az argumentumokkal. Például gyakran használhatja az ls parancsot az l és t opciókkal:
$ ls –lt
A parancs kiadásával járó gépelés mennyiségének csökkentése érdekében lehetőség van egy alias létrehozására, amely leképezi a parancsot és az argumentumokat. Például egy olyan alias létrehozásához, hogy az l betű beírása az ls -lt parancs végrehajtását eredményezze, a következő utasítást kell használni:
$ alias l="ls –lt"
Az l beírása a parancssorba most az eredeti utasítást hajtja végre.
1.12 Környezeti változók
A shell környezeti változók az adatok és konfigurációs beállítások ideiglenes tárolását biztosítják. Maga a héj számos környezeti változót állít be, amelyeket a felhasználó megváltoztathat, hogy módosítsa a héj viselkedését. Az aktuálisan definiált változók listáját az env paranccsal kaphatjuk meg:
$ envSSH_CONNECTION=192.168.0.19 61231 192.168.0.28 22MODULES_RUN_QUARANTINE=LD_LIBRARY_PATHLANG=en_US.UTF-8HISTCONTROL=ignoredupsHOSTNAME=demo-pc.ebookfrenzy.comXDG_SESSION_ID=15MODULES_CMD=/usr/share/Modules/libexec/modulecmd.tclUSER=demoENV=/usr/share/Modules/init/profile.shSELINUX_ROLE_REQUESTED=PWD=/home/demoHOME=/home/demoSSH_CLIENT=192.168.0.19 61231 22SELINUX_LEVEL_REQUESTED= ...
A leghasznosabb környezeti változó talán a PATH. Ez határozza meg, hogy a shell milyen könyvtárakban és milyen sorrendben keressen a parancssorba beírt parancsokat. Egy újonnan telepített Ubuntu rendszerben egy felhasználói fiók PATH környezeti változója valószínűleg a következőképpen lesz beállítva:
$ echo $PATH/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/ bin:/usr/local/sbin:/usr/sbin
A másik hasznos változó a HOME, amely az aktuális felhasználó home könyvtárát adja meg. Ha például azt szeretnénk, hogy a shell az otthoni könyvtárunkban található scripts könyvtárban is keressen parancsokat, akkor a PATH változót a következőképpen módosítjuk:
$ export PATH=$PATH:$HOME/scripts
Egy meglévő környezeti változó aktuális értéke az echo parancs segítségével jeleníthető meg:
$ echo $PATH
A saját környezeti változókat az export parancs segítségével hozhatjuk létre. Például:
$ export DATAPATH=/data/files
Egy hasznos trükk egy parancs kimenetének egy környezeti változóhoz rendeléséhez a parancs körüli idézőjelek (`) használata. Például az aktuális dátum és idő hozzárendelése a NOW nevű környezeti változóhoz:
$ export NOW=`date`$ echo $NOWTue Apr 2 13:48:40 EDT 2020
Ha vannak olyan környezeti változó vagy alias beállítások, amelyeket minden egyes alkalommal, amikor belép a héj környezetébe, konfigurálnia kell, akkor ezeket hozzáadhatja a .bashrc nevű fájlhoz az otthoni könyvtárában. A következő .bashrc fájl például a DATAPATH környezeti változó és egy alias beállítására van beállítva:
# .bashrc # Source global definitionsif ; then . /etc/bashrcfi # User specific environmentPATH="$HOME/.local/bin:$HOME/bin:$PATH"export PATH # Uncomment the following line if you don't like systemctl's auto-paging feature:# export SYSTEMD_PAGER= # User specific aliases and functionsexport DATAPATH=/data/filesalias l="ls -lt"
1.13 Shell szkriptek írása
Az eddigiekben kizárólag a Bash shell interaktív jellegével foglalkoztunk. Interaktív alatt azt értjük, hogy a parancsokat kézzel, egyenként írjuk be a promptba, és hajtjuk végre. Valójában ez csak egy kis része annak, amire a shell képes. Vitathatatlanul a shell egyik legerősebb aspektusa a shell szkriptek létrehozásának lehetősége. A héjszkriptek lényegében olyan szövegfájlok, amelyek olyan utasítássorozatokat tartalmaznak, amelyeket a héj környezetében lehet végrehajtani a feladatok elvégzése érdekében. A parancsok futtatásának képességén kívül a shell számos olyan programozási konstrukciót biztosít, mint például a for és do ciklusok és az if utasítások, amelyeket ésszerűen elvárhatunk egy szkriptnyelvben.
A shell szkriptelés részletes áttekintése sajnos meghaladja ennek a fejezetnek a kereteit. Számos könyv és webes forrás foglalkozik azonban a shell scriptinggel, amelyek sokkal jobban foglalkoznak a témával, mint azt itt valaha is remélhetnénk. Ebben a fejezetben ezért csak egy nagyon kis ízelítőt adunk a héjszkriptelésből.
A héjszkript létrehozásának első lépése egy fájl létrehozása (a példa kedvéért nevezzük el simple.sh), és az első sorba a következőket írjuk be:
#!/bin/sh
A #! karaktert “shebang”-nek nevezzük, és egy speciális karaktersorozat, amely azt jelzi, hogy a szkript végrehajtásához szükséges interpreter elérési útvonala a sorban következő elem (ebben az esetben a /bin könyvtárban található sh futtatható program). Ez ugyanúgy lehetne például /bin/csh vagy /bin/ksh is, ha bármelyik lenne a használni kívánt interpreter.
A következő lépés egy egyszerű szkript megírása:
#!/bin/shfor i in *do echo $idone
A szkript mindössze annyit tesz, hogy végigmegy az aktuális könyvtárban lévő összes fájlon, és megjeleníti az egyes fájlok nevét. Ezt úgy lehet végrehajtani, hogy a szkript nevét argumentumként átadjuk a sh parancsnak:
$ sh simple.sh
A fájl futtathatóvá tételéhez (így nem kell átadni a sh parancsnak) a chmod parancsot használhatjuk:
$ chmod +x simple.sh
Ha a fájl jogosultságainál beállítottuk a execute bitet, közvetlenül végrehajtható. Például:
$ ./simple.sh
1.14 Összegzés
Az Ubuntu Essentials ezen fejezetében röviden megismertük a Bash shell környezetet. A grafikus asztali környezetek világában könnyű elfelejteni, hogy egy operációs rendszer valódi erejét és rugalmasságát gyakran csak úgy lehet kihasználni, ha a felhasználóbarát asztali felület alá ereszkedünk, és shell környezetet használunk. Ráadásul a shell ismerete elengedhetetlen, amikor olyan szerver alapú rendszereket kell adminisztrálni és karbantartani, amelyeken nincs telepítve az asztali felület, vagy amikor olyan rendszert próbálunk megjavítani, amely olyan mértékben sérült, hogy az asztali vagy a Cockpit felület már nem indul el.