3. Hogyan használjuk ?

3.1. Jelentkezzünk be !

Most már (elméletben) elég jól ismerjük a rendszer felépítését: kezdjük el használni is. Egy Linux gép terminálja elé ülve valami hasonlót láthatunk:
Welcome to Linux 1.3.10

claudius login:
Ez a gépen futó kernel verziója, illetve a gép neve (a Unix-os gépeknek nevük van!), valamint a login: prompt jelzi azt, hogy a terminál kész a bejelentkezés fogadására. (Ezek a bejelentkezés előtti üzenetek természetesen konfigurálhatók). Gépeljük be tehát a user-nevünket és a jelszavunkat, és pár sor újabb üzenet után (pl. hogy mikor jelentkeztünk be ezelőtt utoljára), megkapjuk a parancsértelmező prompt-ját, jelen esetben:
claudius:~$
Jelentése: legelőször áll a gép neve, utána kettősponttal elválasztva az aktuális könyvtár (a tilde jel egy rövidítés - a felhasználó ún. home könyvtárát jelenti, amiről mindjárt megtudjuk mi is az). a prompt végét pedig egy $ karakter jelzi. Ha root privilégiumokkal jelentkeztünk volna be, a prompt végén egy # karaktert látnánk - a rendszer ezzel is figyelmeztet különleges hatalmunkra. A home könyvtárról: a rendszeren minden felhasználónak van egy otthona, ahova bejeletkezéskor a rendszer az aktuális könyvtárat (current working directory) állítja: ez a könyvtár a felhasználó tulajdonában van, itt tartja file-jait, ide dolgozik, és ha akarja, el is rejtheti a könyvtár tartalmát a többi felhasználó kíváncsi szeme elől. Ez Linuxokon általában a /home/felhasznalo_nev vagy ritkábban a /usr/users/felhasznalo_nev nevű könyvtár. Rövidítve - mint már láttuk - a ~ jellel hivatkozhatunk rá.

3.2. A parancsértelmező, avagy shell

3.2.1. Miért van rá szükség ?

Egy Unix rendszermag szigorúan véve nem tartalmaz felhasználó-interakciót: a kernel csupán arra képes, hogy futtasson más programokat, illetve hozzáférést biztosítson a rendszer erőforrásaihoz - ezen szolgáltatásait azonban programozói szinten, ún. rendszerhívások ( system calls, vagy röviden syscalls) formájában kínálja. Már a rendszer indításakor szükség van tehát egy (illetve több) programra, amely biztosítja a bejelentkezés lehetőségét, illetve bejelentkezéskor is minden felhasználó számára el kell indítani egy programot, amely lehetővé teszi a felhasználó számára, hogy a rendszerrel kommunikáljon, más programokat indítson el stb. Ez a program a parancsértelmező vagy shell (szokás - elég szerencsétlenül - burokprogramnak is fordítani), amely nem csinál mást, minthogy olvassa a felhasználó billentyűzetéről érkező parancsokat, és ezeket a kernel számára emészthető rendszerhívásokká alakítja, a végeredményről pedig a képernyőn tájékoztatja a felhasználót. Fontos megjegyezni, hogy ilyen szempontból a shell semmiféle speciális tulajdonsággal nem bír: tulajdonképpen bármely programot megadhatunk ún. default shell-nek (cifra magyarsággal alapértelmezés szerinti parancsértelmező). Ha azt akarjuk, hogy valamely felhasználó csak a "vi" szövegszerkesztőt legyen képes futtatni, állítsuk be számára default shell-ként a "vi" programot: ekkor bejelentkezés után rögtön a "vi" indul el, a szövegszerkesztés befejezése (a "vi"-ből kilépés) után pedig a felhasználó visszakerül a login: prompthoz. Sőt, olyan programot is megadhatunk default shell-nek, amely egyáltalán nem olvas a billentyűzetről és nem ír a képernyőre - bár szegény felhasználó számára a bejelentkezések nem lesznek túl érdekfeszítőek - a program lefutását is csak onnét veszi észre, hogy visszakerült a login: prompthoz. Egy hasznos információ: a rendszerből kilépni a shell promptnál a "logout" paranccsal lehet. Hasonló az "exit" parancs is, azonban ez csak az első, a "login shell" után indított shellekből indít el, a rendszerből teljesen kilépni "logout"-tal kell.

3.2.2. Milyen shellek vannak ?

Általában persze nem valamilyen célprogramokat adnak meg shell-ként, illetve célprogramokat: shell céprogramokat, amelyek fő célja, hogy a felhasználót segítsék a rendszer használatában (ami más programok indítását jelent). A Unix hosszú története során a sokféle fejlesztő és felhasználó ízlését tükrözvén, többféle shell program alakult ki: a legelterjedtebbek: a legelső, az ősi "sh", a Bourne által megírt shell, amely egyfajta közös nevezőt jelent, mert minden Unix rendszer tartalmazza, aztán az sh továbbfejlesztett és C programozók ízlésvilágához igazított változata a "csh", a sokféle funkciót magában foglaló Korn shell, a "ksh", valamint a csh kényelmi és kiterjesztett funkciókkal jól megpakolt változata a "tcsh", és végül a Linux rendszereken általánosan használt "bash", a Bourne Again SHell, amely az sh egy alaposan továbbfejlesztett változata. A shell lehetőségei nem merülnek ki csupán interaktív parancs-futtatásban: mindegyik shell-nek egy saját kis programnyelve van, amelyben interpretált kis programocskákat (ún. shell script-eket) írhatunk. A shell script programozással később részletesen foglalkozunk majd.

3.2.3. Környezeti változók

Fontos tulajdonsága még a shellnek, hogy definiálhatunk benne (a DOS-hoz hasonló) ún. környezeti változókat (enviroment variables), amelyek közül a fontosabbak: a PATH változó, amely megmondja, mely könyvtárakban keresse a rendszer a futtatható file-okat, a HOME változó, amely a home könyvtár útvonalát tartalmazza, a LOGNAME és a HOSTNAME változók, amelyek a login nevet illetve a gép nevét tartalmazzák, illetve a TERM változó, amely a használt terminál típust azonosítja.

3.2.4. Különbségek az egyes shellek között

Alapvető vonásaiban minden shell azonos: programot elindítani mindegyikben a programnév begépelésével lehet, mindegyik azonosan értelmezi a file-név metakaraktereket, és végülis amit egyik shellben meg tudunk csinálni, az több-kevesebb nehézséggel egy másikban is elérhetjük - bár néha eltérő szintaktikával. Például a környezeti változók állítása már nem ugyanazzal a szintaktikával történik az egyes shellekben, az elért hatás azonban ugyanaz. Lényegi különbség nincs igazán a shellek között, talán csak annyi, hogy az újabbakban sok olyan - gépelést megtakarító, gyorsító - funkció van amelyek a régebbi shellekben még nem voltak meg. A továbbiakban bash-ban fogunk dolgozni, mert - bár létezik Linuxra az összes említett shell - mégis a Linux világban ez a legelterjedtebb.

Térjünk tehát vissza gépünk promptjához, amelyről most már tudjuk, hogy a shell írja ki (a ~ rövidítést is a shell értelmezi).

3.2.5. Néhány hasznos ismeret a bash-ról

A bash számos kényelmi funkciója közül néhány: Az előzőleg begépelt parancsokat visszahívhatjuk a felfelé nyíllal, a parancssort szabadon szerkeszthetjük (mozogni a nyílbillentyűkkel lehet). Előző parancsot visszahívni még a felkiáltójellel is lehet: a ! mögé rövid sztringet írva megkeresi a legutóbbi olyan parancsot, amely azzal a sztringgel kezdődött, és azt futtatja le. A ! használatával előhívott parancs egyébként módosítható, át is szerkeszthető. File-név kiegészítést a "Tab"-bal kérhetünk: ennek hatására a shell megpróbálja kiegészíteni az eddig begépelt file-név kezdeményt. Ha ez egyértelműen lehetséges, beírja a file-nevet, ha nem, sípol egyet, és a "Tab" újbóli megnyomására megkapjuk a lehetséges file-nevek listáját. A file-név kiegészítés valamennyire intelligens: sor elején (első szóban) csak futtatható file-okra, parancsok nevére egészít ki (viszont a PATH-ot is végignézi), argumentumoknál viszont az aktuális könyvtár (vagy a megkezdett file-névnek megfelelő könyvtár) összes file-jára működik.

Még két, a bash-hoz tartozó file-ról érdemes beszélnünk, mindkettő a home könyvtárunkban van, és shell parancsokat tartalmaz, amelyeket a bash bizonyos körülmények között végrehajt. Az első a .profile, amelyet bejelentkezéskor hajt végre a rendszer, a másik pedig a .bashrc, amelyet minden bash indításkor (tehát akkor is, ha már bejelentkezünk és újabb shellt indítunk). A .profile-ban szokás például a PATH és más globális változók értékét saját ízlésünk szerint konfigurálni, a .bashrc-ben pedig például "alias"-okat definiálhatunk: "alias"-ok segítségével parancsoknak más neveket adhatunk, hosszú parancsoknak rövideket vagy nehezen megjegyezhető nevűeknek valami memorizálhatóbbat. DOS mániákusok például írhatják a következőt:

claudius:~$ alias dir='ls -l'
Ezután a "dir" parancs jelentése "ls -l" lesz. Az eddig (vagy előre) definiált alias-okat a paraméterek nélkül kiadott "alias" paranccsal nézhetjük meg, egy alias-t kitörölni pedig az "unalias alias_nev" paranccsal lehet. "Folytatható" alias-t (ahol az alias helyettesítése után az alias név után írt szavakat is továbbviszi a shell), az alias végére írt $* szimbólummal definiálhatunk.

3.3. Parancsok futtatása

3.3.1. Az ls parancs

Már tudjuk, hogy programot indítani nevének begépelésével lehet. Ekkor ha csak a file-nevet adtuk meg, akkor a rendszer végignézi a PATH változóban szereplő könyvtárakat, és ha valamelyikben megtalálja a file-t és ha az futtatható, akkor elindítja. Vigyázat! Az aktuális könyvtárban csak akkor nézi meg, ha a PATH-ban meg van adva a . is, mint könyvtár. Ha a file-nevet útvonallal együtt adtuk meg, akkor csak az adott helyen lévő file-ot próbálja meg végrehajtani (pl. /bin/ls, vagy hivatkozás az aktuális könyvtárban lévő file-ra: ./ls ). Futtassuk tehát az ominózus ls parancsot, amely hasonlóan a DOS "dir" parancsához, kilistázza az adott könyvtárban lévő file-ok neveit:
claudius:~$ ls
LaTeX/			egyeb/			pi*
Mail/			hun.kbd			xtermdos.zip
News/			linuxmop-0.01.README	yp-clients-1.5.patch
WWW/			linuxmop-0.01.tar.gz
ch-1-k.ps		lx-1.3.tgz
A parancs a file-neveket abc rendben írja ki. A file-név mögött lévő / azt jelenti, hogy egy alkönyvtárról van szó, a * pedig futtatható file-t jelez. Ezeknek az információknak a jelzéséhez az ls-t külön paraméterezni kell: alapértelmezés szerint csak a file-ok neveit írná ki.

3.3.2. Ismét pár szó a környezeti változókról

Ezek a paraméterek előre be vannak állítva munkakörnyezetünkben: az ls parancs opcióként használja az LS_OPTIONS környezeti változóban beállított sztringet. Nézzük meg:
claudius:~$ echo $LS_OPTIONS
--8bit --color=tty -F -T 0
Az egyes opciók jelentésével nem kell most törődnünk - elég azt látni, hogy környezeti változó értékét az "echo " paranccsal írathatjuk ki, a változó neve elé egy $ jelet írva (környezeti változók esetén a változó neve elé írt $ -ral érhetjük el, hogy a változó neve mint sztring helyébe a shell helyettesítse a változó tartalmát). Nézzük meg néhány további változó értékét:
claudius:~$ echo $HOME      
/usr/users/tiv
claudius:~$ echo $LOGNAME
tiv
claudius:~$ echo $PATH
/usr/local/bin:/bin:/usr/bin:.:/usr/X11/bin:/usr/andrew/bin:/usr/openwin/bin:/usr/games:.:/usr/TeX/bin
Az "echo " paranccsal egyébként nem csak környezeti változók értékét irathatjuk ki: a parancs ugyanis nem csinál mást, minthogy az argumentumként kapott sztringe(ke)t egyszerűen kiírja - esetünkben is a változó-helyettesítést a shell végzi. Környezeti változónak értéket adni a valtozo_nev=ertek utasítással lehet. Például:
claudius:~$ valtozo=valami
claudius:~$ echo $valtozo
valami
Megkülönböztetünk ún. lokális (csak éppen futó shell alatt érvényes) változókat, illetve globális, egész bejelentezésünk ideje alatt minden indított programban érvényes változókat (például a PATH-nak ilyennek kell lennie). Környezeti változót globálissá az "export" utasítással tehetünk. Egy könyvtár hozzáadása a PATH-hoz:
claudius:~$ PATH=/alma/jonatan:$PATH
claudius:~$ export PATH 
Vagy akár össze is vonhatjuk:
claudius:~$ export PATH=/alma/jonatan:$PATH
Mint látható, a PATH-ban az egyes könyvtárnevek kettősponttal vannak elválasztva. Ha a behelyettesítendő környezeti változó után rögtön szöveget akarunk írni (mondjuk a környezeti változó egy sztring része), akkor a ${valozo_nev} szintakszist használjuk, ezzel világosan el lehet különíteni a változó nevét a körülvevő egyéb karakterektől. Az éppen definiált összes környezeti változó nevét és értékét az "env" paranccsal irathatjuk ki.

3.3.3. Még pár szó az ls parancsról

Térjünk most vissza az ls parancshoz! Az ls tipikus Unix parancs, amennyiben egy kis, rövid önálló futtatható program, amelynek argumentumokat és opciókat adhatunk meg, és futása végedményét a kimenetre (jelen esetben ez a képernyő) írja. Nézzünk meg néhány gyakran használt opciót:
claudius:~$ ls -a
./			Mail/			pi*
../			News/			xtermdos.zip
.bash_history		WWW/			yp-clients-1.5.patch
.elm/			ch-1-k.ps
.netrc			egyeb/
.newsrc			hun.kbd
.profile*		linuxmop-0.01.README
.rhosts			linuxmop-0.01.tar.gz
LaTeX/			lx-1.3.tgz
Most az előzőeken kívül kiírt még egy csomó ponttal kezdődő nevű file-ot is: ezek a file-ok az előbb is ott voltak a könyvtárban, csak az ls alapértelmezés szerint nem írja őket ki: konvenció szerint ezen file-ok legtöbbje ún. inicializáló file, amelyekre normál munkánk során általában nem vagyunk kíváncsiak. Például a .profile egy olyan file, amelybe azokat az utasításokat írjuk, amelyeket szeretnénk hogy minden bejelentkezéskor végrehajtson a rendszer: tudjuk hogy ez a file ott van, de nem szeretnénk, hogy minden egyes ls kiadásakor foglalja a képernyőn a helyet. Hasonló a helyzet a többi ponttal kezdődő file esetén is. Még egy fontos ls opció:
claudius:~$ ls -l

drwxr-xr-x   2 tiv      users        1024 Jun 10 11:10 LaTex/
drwx------   2 tiv      users        1024 Jul 18 23:27 Mail/
drwx------   2 tiv      users        2048 Jun 30 11:24 News/
drwxr-xr-x   3 tiv      users        1024 May 15 14:56 WWW/
-rw-r--r--   1 tiv      users      203839 Jun  5 13:31 ch-1-k.ps
drwxr-xr-x   2 tiv      users        1024 Jan 15  1995 egyeb/
-rw-r--r--   1 tiv      users         613 Apr  2 15:52 hun.kbd
-rw-r--r--   1 tiv      users         136 Jun 29 17:39 linuxmop-0.01.README
-rw-r--r--   1 tiv      users      159303 Jun 29 17:37 linuxmop-0.01.tar.gz
-rw-r--r--   1 tiv      users     1374657 Jun 21 15:08 lx-1.3.tgz
lrwxrwxrwx   1 tiv      users          17 Jul 20 09:01 vmessages -> /var/adm/mes
sages
-rw-rw-r--   1 tiv      users      276578 May 25 09:10 xtermdos.zip
-rw-------   1 tiv      users         577 Feb  8 14:31 yp-clients-1.5.patch

3.3.4. A file-típusok

-l -lel (long listing) minden egyes file-ról "bő" (verbose) információt kaphatunk. Az egyes mezők jelentése: A legelső karakter a file típusára utal:
d
ha a file egy könyvtár (directory)
b
ha a file block típusú speciális file
c
ha a file karakter típusú speciális file
l
ha a file szimbolikus link
s
ha a file socket
-
ha a file "egyszerű" (plain) file
(A b,c,s típusú file-okat később majd tárgyaljuk: egyenlőre fogadjuk el, hogy ilyenek is vannak).

3.3.5. A hozzáférési jogosultságok

A következő 3*3 karakter a file hozzáférési jogosultságait adja meg: az első három karakter jelenti, hogy a file tulajdonosa mit tehet a file-lal:
r
ha olvashatja (read)
w
ha írhatja (write)
x
ha végrehajthatja (execute)
-
ha az adott jog nincs számára megadva
A kövekező három karakter ugyanilyen formában jelenti a file-tulajdonos csoport (group) jogait, vagyis hogy a file tulajdonos csoportba tartozó felhasználók mit tehetnek az adott file-lal, az utolsó három karakter pedig a külvilág (others), az egyéb felhasználók jogait jelenti. A file tulajdonosa természetesen tetszés szerint megadhatja a hozzáférési jogokat, nemsokára látni fogjuk hogyan. Azt tehát, hogy egy file futtatható-e (az operációs rendszer megkísérelheti-e futtatni) Unix alatt nem kiterjesztés, vagy más egyéb file-névbe olvasztott információ dönti el, hanem a megfelelő x attribútum. Az is igaz, hogy ha egy file-ra csak x jogunk van, akkor csak futtatni fogjuk tudni azt a file-t, olvasni nem - tehát nem fogjuk tudni lemásolni sem! Mint már láttuk, szöveges file is lehet futtatható: a shell parancsokat tartalmazó shell script-ek is egyszerű szöveges file-ok, beállított x attribútummal. Ha egy ilyen file-t indítunk el, a shell egyszerűen soronként olvassa és hajtja végre a beleírt utasításokat, hasonlóan a DOS-os .BAT file-okhoz. A végrehajtási jog ("x") könyvtárak esetén a könyvtárban való keresés jogát jelenti. Ha valamely műveletünk megfelelő jogosultságok hiányában meghiúsul, a sokat átkozott "Permission denied." hibaüzenetet láthatjuk.

3.3.6. A file-okhoz tartozó egyéb információk

A jogok után következő mező a sorban az úgynevezett link számláló (link count): megadja, hogy az adott filesystem-en hány hard link mutat az adott file-ra (tulajdonképpen megmondja, hogy hány néven hivatkozhatunk a file-ra). Ez a számláló csak a hard linkek számát mutatja - szimbolikus linkek számolására nincs lehetőség.

A következő mező a file tulajdonos user-neve (jelen esetben "tiv"), a következő pedig a tulajdonos csoport azonosítója ("users"). Ezután a file hossza következik byte-okban, majd az ún. "mtime" mező, a file utolsó módosításának dátuma. Legvégül a file neve látható. Szimbolikus linkeknél (a fenti példában a "vmessages" file ilyen) a -l opció hatására egy -> nyíl után az ls kiírja, melyik másik file-ra mutat a szimbolikus link.

3.3.7. Unix parancsok paraméterezése

Az ls parancsnak azt is megadhatjuk, melyik könyvtárat listázza (ha nem adunk meg semmit, az aktuális könyvtár tartalmát írja ki). A gyökér- könyvtár és mondjuk a /usr/users/tiv/ch-1-k.ps file lehető legteljesebb listázása így nézhet ki:
claudius:~$ ls -la / /usr/users/ch-1-k.ps
Argumentumként akár több file- vagy könyvtárnevet is megadhatunk, és amint láttuk, az opciókat összevonhatjuk. Általánosságban, egy tipikus Unix parancs hívási formája a következő:
parancsnév [opció(k)] [argumentum(ok)]
Ha egy paramétereket igénylő parancsot paraméterek nélkül, vagy nyilvánvalóan hibás paraméterezéssel hívunk meg, általában a parancs rövid segítséget ír ki a helyes paraméterezésről.

3.4. Még néhány alapvető file-kezelő parancs

Aktuális könyvtárat a "cd" paranccsal válthatunk - a DOS-tól eltérően argumentumok nélkül kiadva azonban nem az aktuális könyvtárat írja ki, hanem visszavisz bennünket a home könyvtárunkba. Az aktuális könyvtár nevét a "pwd" (print working directory) paranccsal kérdezhetjük le:
claudius:~$ pwd    
/usr/users/tiv
claudius:~$ cd /usr/local
claudius:/usr/local$ cd ../..
claudius:/$ pwd
/
claudius:/$ cd
claudius:~$ pwd
/usr/users/tiv
File-ot másolni a "cp" (copy) paranccsal tudunk, ("cp [opciók] mit hova" szintaktikával). Hasznos opciói a -r (rekurzív másolás) illetve a -i (interactive) amely ha már létezik a cél-file, felülírása előtt rákérdez, biztosak vagyunk-e a dolgunkban.

File mozgatása illetve átnevezése az "mv" (move) paranccsal lehetséges: az argumentumok sorrendje ugyanolyan mint a cp-nél. A mv parancs használható egész könyvtárstruktúrák mozgatására is, de csak egy filesystem-en belül.

Könyvtárat létrehozni a "mkdir dir_nev" utasítással lehet, letörölni pedig az "rmdir dir_nev" paranccsal. Törölni csak üres könyvtárat lehet.

Linkeket az ln [-s] letezo_filenev uj_filenev paranccsal hozhatunk létre - ha megadjuk a -s opciót, szimbolikus link keletkezik, ha nem akkor hard link.

File-okat törölni az "rm" (remove) utasítással lehet. Figyelem! Unix rendszerekben letörölt file visszaállítására NINCS LEHETŐSÉG, legfeljebb biztonsági másolatból. Ezért az rm használata előtt mindig kétszer gondoljuk meg, valóban meg akarunk-e szabadulni attól a file-tól. Hirtelenkezű felhasználóknak találták ki az rm -i opciót, amely minden egyes file letörlése előtt még egyszer visszakérdez. Megfelelő önbizalommal rendelkezők használhatják a -f opciót: ez viszont nem kérdez semmit, sőt ha esetleg nem lenne jogunk a file törlésére, akkor sem szól vissza: amit tud letöröl csendben, amit nem azt ott hagyja. Amennyiben egy file a mi tulajdonunkban áll, de (talán elővigyázatosságból?) levettük róla a "w" jogot (irás - ennek számít a törlés is), a "sima" rm nem törli le a file-t, hanem megkérdezi, felülbírálja-e a törlési jog hiányát (saját file esetén ezt megtehető). A -f opció viszont nem kérdez semmit: átállítja a jogokat és töröl szó nélkül (amennyiben persze teheti). Az rm, mkdir, rmdir parancsoknak több file-nevet is megadhatunk argumentumként: az "rm a b c" mindhárom file-t törli. Ez veszélyes is lehet: az "rm a*" utasítás törli az összes "a"-val kezdődő nevű file-t (a metakarakterekről bővebben majd később), a gépelési hiba folytán keletkezett "rm a *" parancs pedig először törli az "a" nevű file-t (ha van ilyen), aztán pedig az aktuális könyvtárban lévő összes többit... (a * minden file-névre illeszkedik). Van az rm-nek még egy gyakran használt, de nagyon veszélyes opciója, ez pedig a -r (rekurzív törlés). Egész könyvtárstruktúrákat törölhetünk vele pillanatok alatt. És - ezt nem lehet elégszer hangsúlyozni: ha egyszer valamit letöröltünk, nincs visszaút!

3.5. File-ok tulajdonságainak manipulációja

3.5.1. File attribútumok

File-attribútumok megváltoztatása, további attribútumok: Mint említettük, a file tulajdonosa tetszés szerint beállíthatja a file védelmi attribútumait: erre szolgál a "chmod" parancs, melynek formátuma:
chmod [opciók] [ugoa...][+-=][rwx...] file_nev 
(Az opciók közül most a -R érdemel említést: ezzel a parancs működése a konyvtárstruktúrában rekurzívvá tehető.) Az egyes betűk jelentése:
u
user: a file tulajdonosra vonatkozó jogok
g
group: a csoportjogok
o
other: mindenki más jogai
a
all: mindhárom csoportra vonatkozó művelet
A műveletek:
+
jog (attribútum) megadása
-
a jog megvonása
=
az attribútumok legyenek a maszk-kal pontosan egyenlők
Ezután pedig az attribútumokból képzett maszk következik. Néhány példa:
claudius:~$ ls -l alma
-rw-r--r--   1 tiv      users           5 Jul 20 10:14 alma
claudius:~$ chmod u-w alma
claudius:~$ ls -l alma 
-r--r--r--   1 tiv      users           5 Jul 20 10:14 alma
claudius:~$ chmod g=rwx alma
-r--rwxr--   1 tiv      users           5 Jul 20 10:14 alma*
claudius:~$ chmod a=r alma
claudius:~$ ls -l alma
-r--r--r--   1 tiv      users           5 Jul 20 10:14 alma
claudius:~$ chmod u+w alma
claudius:~$ ls -l alma
-rw-r--r--   1 tiv      users           5 Jul 20 10:14 alma
Még két (pontosabban három) attribútumot fontos itt megemlítenünk: az első az ún. "sticky" attribútum (jele "t"), amely futtatható file esetén azt jelenti, hogy a program lefutása után az operációs rendszer a program kódját megpróbálja a memóriában tartani, így legközelebbi indításkor nem kell megvárni a program betöltődését. Ezt a funkciót azonban nem minden Unixban valósították meg, és napjainkban a "demand paging" technikák miatt egyre inkább jelentőségét veszti. Legjobb tudomásom szerint ez a funkció Linuxban sincs implementálva. Ha a "t" attribútum könyvtárra van kiadva, azt jelenti, hogy hiába van az egész könyvtárra írási jogom, mégis csak a saját tulajdonomban lévő file-okat törölhetem le. Amennyiben ugyanis egy könyvtárra irási jogom van, ebből a köyvtárból törölhetem a mások által létrehozott file-okat is, még akkor is, ha magukra a file-okra nincs irási jogom. Viszont ha a "sticky bit" be van állítva, csak a saját file-jaimat pusztíthatom. A másik két fontos attribútum még a "set-UID" és a "set-GID" bitek: jelentésük, hogy (futtatható programnál van értelme használni őket) a futó program a program file tulajdonos felhasználó vagy csoport jogaival fog rendelkezni (de csak a futás idejére!) függetlenül attól, ki is indította el. Hogy mire jó ez? Képzeljük el, hogy valaki meg akarja változtatni a jelszavát (amire a "passwd" parancs való)! Ekkor át kell írni a csak root által írható kódolt jelszófile-ban a felhasznaló jelszavát - de hogy ezt bármelyik felhasználó megtehesse, és ne kelljen minden jelszóváltáskor a rendszergazdát felkeresni, a "passwd" programnak root jogokkal kell futnia. Természetesen a "passwd" programba bele vannak építve a megfelelő biztonsági mechanizmusok arra, hogy mindenki csak a saját jelszavát legyen képes módosítani.

A rendszer belsőleg ezeket a file attribútumokat (file permission bits) numerikusan tárolja, és a chmod parancsnak is megadhatjuk numerikusan, mégpedig oktális szám formájában. Például:

claudius:~$ chmod 467 alma
claudius:~$ ls -l alma
-r--rw-rwx   1 tiv      users           5 Jul 20 10:14 alma
Amiből észrevehetjük, hogy az egyes számjegyek jelentik az egyes felhasználó(csoport)ra vonatkozó engedélyeket, kiszámításuk pedig: x = 1, w = 2, r = 4, és az egyes számjegyekbe a kívánt módok összegét kell írni.

3.5.2. File-ok tulajdonjogának állítása

File-ok tulajdonjogát a "chown [-R] user file" paranccsal állíthatjuk, (ezt csak a root teheti meg, saját magunk nem adhatunk át file-t másoknak), a csoport tulajdonjogot pedig a "chgrp [-R] group file" utasítással állíthatjuk. Ezt az utasítást felhasználók is használhatják, amennyiben mindkét csoport tagjai, és a file tulajdonosai is egyben.

3.6. Egy gyakran használt parancs: a man

Unix alatt is rendelkezésre áll on-line help rendszer, amelyet a "man" (manual pages - kézikönyv) utasítással hívhatunk elő. Ez, mint egy valódi kézikönyv, nem arra szolgál, hogy ebből sajátítsuk el a Unix használatát - sokkal inkább referencia jellegű, az egyes parancsok, függvények, file-formátumok rövid, de pontos ismertetésével. Ha tudjuk, hogy könyvtár tartalmát az "ls" paranccsal listázhatjuk ki, de nem emlékszünk melyik opciójával kaphatjuk meg a bő (long) listát, csak gépeljük be: "man ls" és máris megkapjuk a ls parancs teljes és minden opcióra kiterjedő leírását. A manual, mint egy rendes kézikönyv, fejezetekre van osztva, és ha esetleg előfordul két azonos címszó, a fejezetszám megadásával tehetjük kérdésünket egyérteművé.

Az egyes fejezetek:

  1. A shell-ből, átlagfelhasználó számára használható parancsok (segédprogramok, utility-k, mint az ls és a chgrp)
  2. A kernel rendszerhívásai, C szintakszis szerint megadva - programozók számára érdekes
  3. A rendszerkönyvtárakban (programkönyvtárakról - libraries - van szó) található könyvtári függvények leírásai, szintén C programozóknak
  4. A rendszer néhány fontosabb állományának formátuma
  5. Szintén állomány- és adatformátumok
  6. A rendszeren található játékprogramok leírásai
  7. Perifériaállományok, speciális file-ok formátumainak specifikációja, a kűlönboző perifériavezérlő parancsok leírása. Rendszerprogramozók számára emészthető formában.
  8. A rendszeradminisztrátor számára futtatható parancsok.
Néhány fejezet alfejezetekkel is rendelkezik, pl. 3x, 3tcl aholis ezek a jelölések az egyes programcsoportok közti jobb eligazodást segítik. Fejezetre hivatkozni a man parancsban a kért lap (manual page) elé írt fejezetszámmal lehet: létezik például a "chown" utasítás mellett chown rendszerhívás is: az utasításról a "man 1 chown" paranccsal, míg a rendszerhívásról a "man 2 chown" -nal kaphatunk segítséget. A man parancs kimenete valamilyen tördelőprogram segítségével kultúráltan, képernyőoldalakra tördelve jelenik meg - általában a "space" billentyűvel lapozhatunk előre egy képernyőoldalnyit, "b"-vel lapozhatunk vissza, "Enter-rel" görgethetünk csak egy sort, és "q"-val léphetünk ki. "h"-val a lapozó program parancsairól kérhetünk gyors segítséget.

Minden manual oldalnak van egy egysoros címe, ezekben keresgélhetünk is a "man -k szo " paranccsal: ekkor kilistázódnak azoknak a manual oldalcímek, amelyek tartalmazzák a keresett szót - előszőr a címhez tartozó címszót, aztán zárójelben a fejezet számát, végül az oldal rövid leírását kapjuk meg. Tanácsos minden eddig említett és ezután említendő parancsot, file formátumot megnéznünk a "man"-ban: az itt csak megemlített lehetőségekről részletes magyarázatot, az alkalmazáshoz további példákat találhatunk.

3.7. I/O átirányítás a Unixban

3.7.1. A standard file-leírók

A Unix rendszer file-orientált szervezése a parancsok futtatásakor is megmutatkozik: minden egyes futó parancshoz hozzárendelődik három file: Alapértelmezés szerint ezen file-ok hozzárendelése a következő: a standard input a terminál billentyűzetéhez van rendelve, a standard output és a standard error pedig a képernyőhöz. Egy tipikus program pedig a következőképpen fut: olvassa a bemenetét a standard inputról, ebből előállít valamilyen eredményt, amelyet a standard outputra ír, az esetlegesen előforduló hibákat pedig a standard error file-ba írja. Ezeket a standard file-hozzárendeléseket a shell segítségével könnyen megváltoztathatjuk, például ha azt akarjuk, hogy az ls parancs ne a képernyőre, hanem mondjuk a "lista" nevű file-ba írja a kimenetét, használjuk a "ls >lista" parancsot! Ekkor, ha már létezett "lista" nevű file, az felülíródik: ha a kimenetet az eddigi file-hoz hozzá akarjuk fűzni, használjuk a "ls >>lista" formulát. A standard input megváltoztatása hasonlóan egyszerű: a "parancs <bemenet" hatására a "parancs" program a bemenet nevű file-ból fogja venni inputját. A standard hiba átirányítása: "program 2>hiba", ennek hatására a hibakimenet a "hiba" file-ba kerül. Természetesen lehetőség van egyszerre többféle átirányításra is: akár a "parancs <bemenet >>kimenet 2>hiba" utasításnak is van értelme. Sőt, meg azt is megcsinálhatjuk, hogy a standard error-t "egybeirányitjuk" a standard outputtal, és a kettőt egy közös file-ba irjuk: "parancs >file_nev 2>&1" . Ezek a dolgok (standard file-ok átirányítása, stadard file redirection) már erősen shellfüggő szintaktikájúak: bár mindegyik shellben meg tudjuk ugyanezeket csinálni, az itt ismertetett szintakszis csak a "bash"-ben működik.

Mire lehet ezeket a lehetőségeket használni ? Van például Unixban egy "more" nevű programocska, amely annyit tesz, hogy olvassa a standard inputját, és az olvasottakat képernyőnként tördelve írja ki a kimenetre, minden képernyőváltás között egy space-leütést várva. (A "more"-ból a "q" leütésével léphetünk ki). A "man"-nál már találkozhattunk is vele. Tegyük fel, hogy sok-sok file van a könyvtárunkban, és szeretnénk őket alaposan végignézni, de az ls parancs kimenete mindig kifut a képernyőről. Tehetjük a következőt:

claudius:~$ ls -l >tmpfile
claudius:~$ more <tmpfile
[nézelődés]
claudius:~$ rm tmpfile 
Egy sorba több parancsot pontosvesszővel elválasztva írhatunk, tehát a fentieket összevonhatjuk:
claudius:~$ ls -l >tmpfile ; more <tmpfile ; rm tmpfile 
Ekkor a shell megvárja az előző parancs lefutását, és utána indítja a pontosvessző utáni parancsot. De ez a megoldás még mindig borzasztóan esetlen, Unixban pedig minden olyan egyszerű és kézenfekvő: biztos lehet ezt egyszerűbben is csinálni!

3.7.2. Programok összekötése

Erre találták fel a "pipe" (csővezeték) intézményét, amely nem csinál mást, mint a pipe bal oldalán álló program standard outputját hozzáköti a pipe jobb oldalán lévő program standard inputjához:
claudius:~$ ls -l | more
Fontos különbség, hogy itt a shell egyszerre elindítja mind a két programot, tehát nem az történik, mint az előbb, hogy először lefut az ls, és aztán írja ki a valahol eltárolt kimenetet a more: itt az ls futása közben, amint megjelenik valami kimenet, a more rögtön megkapja azt és akcióba lép. A pipe kapcsán még egy hasznos parancsot érdemes megemlítenünk (bár ez már inkább a következő részbe, a szűrők közé tartozik: a "tee" parancsot, amellyel standard output elágaztatást érhetünk el: a tee parancs a standard inputját a standard outputra valamint a paramétereként magadott file-ba másolja. Leginkább programkövetéskor, belövéskor hasznos, amikor nyomon szeretnénk követni a pipe belsejében zajló történéseket.

3.8. A szűrőkről (filters)

A Unix parancsok jó része nem csinál mást (a more-hoz hasonlóan), minthogy olvassa standard inputját (jellemzően szövegsor-orientáltan) a beolvasott inputtal "valamit csinál", majd az inputot, esetleg annak egy részét, vagy valamely, az inputtól függő mennyiséget, adatot a standard outputra ír. A programok ezen csoportját nevezzük szűrőknek (filters). A szűrők általános tulajdonsága továbbá, hogy első argumentumként egy file-nevet megadva standard inputjukat abból a file-ból veszik, tehát a "more <hosszu_file" és a "more hosszu_file" parancsok tulajdonképpen ekvivalensek: a különbség annyi, hogy az első esetben a more-nak mint programnak nincs egy argumentuma sem, az input-átirányítást a shell végzi, a második esetben pedig a more parancs tudja, hogy argumentummal indítottuk el, és ő maga intézi úgy, hogy a bemenetet a megadott file-ból olvassa. A továbbiakban néhány hasznos szűrőt nézünk meg, a teljesség igénye nélkül. Közös jellemzőjük, hogy apró, önálló segédprogram mindegyik, amelyekből a shell segítségével bonyolult feladatokra képes programfüzérek rakhatók össze.

A legegyszerűbb szűrő a "cat", amely nem tesz mást, mint a standard inputját soronként átmásolja a standard outputra. Például:

claudius:~$ cat >proba
Ez egy proba.
Igen.
^D
Az utolsó sorban szereplő karakter a Control-D, rövid jelöléssel ^D, amely a shell számára file-vég karaktert jelent (hasonlóan a DOS Ctrl-Z karakteréhez).

Meg is nézhetjük újonnan gyártott file-unkat:

claudius:~$ cat proba
Ez egy proba.
Igen.
Emlékeztetőül: Irhattunk volna "cat <proba" -t is, a végeredmény ugyanaz lenne. Újabb filter a "wc" (word count), amely az inputján érkező sorokat, szavakat és karaktereket számolja meg, és a végeredményt kiírja:
claudius:~$ cat proba | wc
      2       4      20
(A "wc proba" ugyanezt eredményezte volna.) Az egyik leghasznosabb szűrő a (később részletesen ismertetendő) "grep", amellyel mintaillesztést végezhetünk:
claudius:~$ cat proba | grep gen
Igen.
A grep csak azokat a sorokat engedi tovább kimenetére, amely(ek)ben szerepel a megadott (karakter)minta.

További gyakran használatos szűrő még: a "sort", amely a standard inputon olvasott sorokat valamilyen szempont szerint rendezve írja ki a kimenetre, opciók nékül hívva egyszerűen alfabetikusan rendez, a -r hatására pedig megfordítja a rendezési sorrendet:

claudius:~$ sort -r proba
Igen.
Ez egy proba.
Vagyis a file tartalma soronként fordított abc rendben jelent meg. A sort egyébként képes numerikusan rendezni, vagy akár a sor mezői szerint is: nézzük csak meg a "man"-ban, mennyi mindenre képes.

Sűrűn használják még a "cut"-ot is, amely nevéhez méltóan "horizontális" darabokat képes az inputként adott sorokból kivágni, pl. ha minden sor 3.-9. karakterére vagyunk kíváncsiak:

claudius:~$ cut -c3-9 proba
 egy pr
en.
Nemsokára, a shell még néhány lehetőségének megismerése után majd látni fogjuk, hogyan tudunk ezekből a szűrőkből igazán hatékony programfüzéreket építeni.

3.9. A shell további lehetőségei

3.9.1. Metakarakterek, file-név helyettesítés

File-név helyettesítésre (mint a DOS-ban) Unixban is használhatunk különböző metakaraktereket, sőt, itt sokkal több lehetőségünk van. Egy nagyon lényeges különbség van azonban: a metakarakterek behelyettesítését a shell végzi, a kiadott parancs meghívása előtt, a parancsot már a megfelelően behelyettesített file-nevekkel hívva meg. Szemléletesen láthatjuk ezt, ha meggondoljuk, (és kipróbáljuk), hogy az "echo *" parancs tulajdonképpen az "ls"-sel ekvivalens. Például, ha az aktuális könyvtárban a malac, marha, tehenke file-ok vannak, a "cat m*a*" parancs a cat-ot már két argumentummal hívja meg, úgy minthogyha a "cat malac marha" parancsot írtuk volna be. A leggyakrabban használt metakarakter (mint láttuk) a *, jelentése: 0 vagy több tetszőleges karakter. A file névben bárhol használható, akár "*a*b*" formában is, aminek jelentése: olyan file-név, amelyben valahol egy "a" betű van, utána pedig valahol egy "b". A másik gyakori metakarakter a ?, amellyel egy darab, tetszőleges betűt helyettesíthetünk. Megadhatunk halmazokat is: a "?[afu]?" az olyan 3 betűs file-nevekre illeszkedik, amelyek középső karaktere "a" vagy "f" vagy "u ". A "[0-9A-Z]" halmaz olyan karakterre illeszkedik, amely vagy szám vagy nagybetű. A nyitó szögletes zárójel után tett ^ karakter pedig a halmaz komplementumát jelenti: a shell azokra a karakterekre fog illeszteni, amelyek nincsenek a szögletes zárójelek között felsorolva.

3.9.2 Speciális karakterek semlegesítése

Időnként szükség lehet arra, hogy bizonyos karaktereket a shell helyettesítő hatásától megóvjunk: egyes karaktert a karakter elé írt \ (backslash)-szel védhetünk meg. Ha teszem azt valami oknál fogva olyan file-be akarunk írni, amelynek nevében a * karakter szerepel, ezt például a következőképpen tehetjuk meg: "cat >ab\*c". Hosszabb sztringet a shell behelyettesítéstől megvédeni a ' egyszeres idézőjellel lehet, ez akkor lehet hasznos, ha például a "grep" szűrővel szóközt is tartalmazó kifejezésre szeretnénk illeszteni. Ha egyszerűen beírnánk a paranccssorba a szóközt tartalmazó szöveget, a shell úgy értelmezné, mintha több argumentumot adtunk volna meg. Az " ls '? *' " utasítás például az (eléggé extrém) "kérdőjel szóköz csillag" nevű file-ot listázza ki, ha van ilyen az aktuális könyvtárban, nem pedig először az egybetűs file-neveket keresi, aztán pedig az összes file-nevet listázza. Hasonló szerepet tölt be a " (kettős aposztóf vagy dupla idézőjel), azzal a különbséggel, hogy az aposztrófban lévő sztringben a környezeti- változó helyettesítések kivételével véd meg mindent. Egy bolnyolult példa: az " ls "${HOME}/*" " azt nézi meg, van-e a home könyvtárunkban * nevű file.

A Unix használja a harmadikféle idézőjelet is, a ` -t, (a legtöbb billentyűzeten a bal felső sarokban található), elég érdekes szerepkörben: az ilyen fajta idézőjelbe írt szöveget a shell parancsként értelmezi, a parancsot végrehajtja, és annak kimenetét (standard output) helyettesíti az idézőjeles kifejezés helyére. Az egyéb metakarakterek helyettesítése normálisan történik. Például:

claudius:~$ echo Ebben a konyvtarban `ls | wc | cut -c6-12` db file van.
Ebben a konyvtarban 36 db file van.
Gondoljuk át alaposan a fenti sor tartalmát! Emlékeztetőül annyit, hogy a "cut" szűrő -c opciója a megadott pozíciójú karaktereket vágja ki a sorból.

3.9.3. Programok csoportosítása zárójelezéssel

Lehetőségünk van futtatandó programjaink csoportosítására a "( shell-parancs )" szintakszis segítségével: ez tulajdonképpen annyit tesz, hogy a zárójelbe tett (leggyakrabban komplex, kettőspontot és pipe-ot tartalmazó) shell parancsot egy utasításként kezelhetjük: például a " (cat file1 ; ls ) | wc " paranccsal megtudhatjuk a file1-ben lévő sorok és az aktuális könyvtárban lévő file-ok számának összegét. Vagy egy másik alkalmazás: " cat file1 | ( echo "Most tortenik a file iras" ; cat >file2) " parancs a file2-be történő írás megkezdése előtt kiírja az üzenetet.

3.10. Folyamatok, processzek

3.10.1. Folyamatok a háttérben

Unix alatt egy felhasználó akár több folyamatot is elindíthat - lényegében minden futó program külön folyamatként fut. Egyszerre azonban csak egy folyamattal tudunk kommunikálni (az egy darab billentyűzet miatt), ezt "előtér" (foreground) folyamatnak nevezzük, a többi futó folyamatunkat pedig "háttér" (background) processzeknek. Pl. a Windows-tól eltérően, az előtérben futó folyamat semmilyen szempontból nincs kitüntetett helyzetben, nem élvez nagyobb prioritást - tulajdonképpen a futtató kernel nem is tudja, melyik folyamat van előtérben, hiszen az ő néző- pontjából mindegyik folyamat ugyanolyan file-műveleteket végez. Folyamatot a program neve után írt & jellel indíthatunk a háttérben: az így indított folyamatnak nem lesz standard inputja (megáll és várakozik, ha a program bemenetről akar olvasni), a standard outputja pedig a shell standard outputja (vagyis a képenyőnk) lesz. Próbáljuk is ki:
claudius:~$ cat &
[1] 1103
A szögletes zárójelben lévő 1-es a folyamat ún. job-azonosítója, a másik szám pedig a folyamat processz-azonosítója. A job azonosítót a shell rendeli az elindított programhoz, azért hogy a felhasználónak ne kelljen a gyakran 5 számjegyű processz-azonosítót (PID) megjegyeznie. Ha ezután kiadunk egy újabb parancsot:
claudius:~$ ls valami
valami
[1]+  Stopped (tty input)     cat
A következő parancs lefutása után a shell észreveszi, hogy az 1-es sorszámú job terminál inputra vár. Háttérfolyamatot előtérbe hozni a
claudius:~$ fg %1
cat
"fg" paranccsal tudunk. Ekkor a folyamatot úgy használhatjuk, mintha a & jel nélkül indítottuk volna el. Ha egy másik programmal szeretnénk foglalkozni, de azt akarjuk hogy az előtérben lévő folyamat tovább fusson a háttérben, a ^Z (Control-Z) billentyűkombinációval megállíthatjuk (ekkor várakozó, "stopped" állapotba kerül), majd háttérbe helyezni a "bg %job-azonositó" paranccsal tudjuk. Ha a folyamat futásképes, (nem vár mondjuk terminál inputra) akkor a háttérben tovább fog futni. Kilépéskor, ha vannak még háttérben futó vagy várakozó folyamataink, a rendszer erre figyelmeztet a "You have running jobs." vagy "You have stopped jobs." üzenettel: ha közvetlenül ez után még egyszer beírjuk a "logout" parancsot, a shell kiirtja a háttérfolyamatokat és kiléptet bennünket a rendszerből. Ha "fg" és "bg" parancsokat argumentum nélkül használjuk, mindig a legutoljára hivatkozott folyamatra vonatkoznak.

Ha több folyamat is fut, amelynek kimenete a képernyő, a shell nem válogatja szét az egyes parancsok outputjait: "ömlesztve" kapunk meg mindent. Ha programfuttatás közben üzenetet kapunk (a rendszertől vagy másik felhasználótól) akkor ez is egyszerűen kiiródik a képernyőre, esetleg jól összekeveredve az éppen futó program kimenetével. Ezért erre mindig érdemes odafigyelni: ha látszólag értelmetlen szöveg jelenik meg a képernyőn, nézzük meg, nincs-e összekeveredve két program kimenete. Az ilyen esetek nagy részét azért elkerülhetjük a háttérben futó programok kimenetének file-ba iranyításával.

Unix alatt a folyamatok hierarchikus rendszerbe szervezettek: minden folyamatnak van szülője. Folyamat csak másik folyamat gyermekeként jöhet lére (az egyetlen speciális, rendszerindításkor keletkező "init" kivételével). Gyermekfolyamat létrehozása a szülő folyamat lemásolásával történik, a már megismert copy-on-write mechanizmus használatával. A gyermek folyamat ezért örökli a szülő minden tulajdonságát, jellemzőjét - még nyitott file-jait is! Ez az oka annak, hogy időnként a shell és az általa indított folyamatok (az ő gyermekei) output-ja összekeveredik: ugyanazt a nyitott file-t írják, és közös file-pozíció mutatót használnak. Kilépéskor a gyermek folyamatok szulőjüknek adják vissza visszatérési értéküket.

Egy működő Unix rendszerben sok olyan folyamat fut még, amely nem tartozik egyik felhasználóhoz sem: root-ként futnak, a rendszer indításakor (boot-oláskor) indulnak, és a rendszer működéséért felelősek. Ezeket a folyamatokat daemon processzeknek nevezzük. Tipikus daemon processz például az "update", amely azért felelős, hogy a buffer cache tartalma bizonyos időközönként (általában 30 másodperc) szinkronizálódjon a diszk fizikai tartalmával. (Magyarul fél percenként kírja a diszkre az addig még ki nem írt változtatásokat). Ezt egyébként a "sync" paranccsal bármikor mi is megtehetjük. A daemon folyamatok tipikusan valami esemény beköveztére v'arakoznak, és az esemény bekövetkeztekor aktivizálódnak.

3.10.2. Sokáig futó vagy időzített folyamatok

Lehetőségünk van azonban arra is, hogy egy folyamatot immunissá tegyünk kilépésünkre: hosszan, több óráig, több napig futó programokat a "nohup" paranccsal indíthatunk. Például:
claudius:~$ nohup program >outputfile <inputfile &
[1] 88
Ekkor a program kilépésünk után is tovább fut, és amint láttuk, gondoskodtunk arról, hogy a programfutás eredményei az "outputfile"-ban megőrződjenek. Egyes shell-ekben a nohup-pal indított parancsok kimenete automatikusan a "nohup.out" file-ba kerül. Ha fut a gépünkön a "cron" nevű program (általában minden Unixon fut) akkor lehetőségünk van időzített programindításra is az "at" paranccsal:
claudius:~$ at 3am program &
[3] 116
Ennek hatására a "program" parancs hajnali háromkor elindul. Természetesen itt is érdemes a futási eredményt megfelelő file-ba menteni.

3.10.3. Folyamataink listázása: a ps parancs

A rendszerben aktuálisan lévő folyamatokról a "ps" (processes) paranccsal kérhetünk információt. Alapértelmezés szerint csak az általunk indított folyamatokat listázza ki:
claudius:~$ ps
  PID TTY STAT  TIME COMMAND
   79 pp0 S     0:00 -bash
  129 pp0 R     0:00 ps
Ami azt jelenti, hogy ebben a pillanatban két processzel rendelkezünk: az első a shell, a második pedig maga a ps parancs. Az egyes mezők jelentése:
PID
a folyamat azonosítója
TTY
a vezérlő terminál azonosítója, jelen esetben ez a ttyp0
STAT
a folyamat állapota, bővebben lásd a "man ps" alatt
TIME
a processz által eddig elhasznált processzor idő
A rendszerben futó összes folyamatot, a legbővebb információkkal Linux alatt a "ps -aux" opciókkal kérhetjük le. Ekkor az processzekről megtudjuk még tulajdonosukat, az időpontot amikor elindultak, valamint különféle erőforrás használati információkat (CPU, memória használat, a program mérete a memóriában). Hasznos segédprogram még a "top", amellyel hasonló információkat kaphatunk, plusz még statisztikákat a rendszer egészéről. A top folyamatosan fut, és 5 másodpercenként frissíti a megjelenített információkat. Kilépni a "q" megnyomásával lehet.

3.10.4. Üzenetek a processzeknek: szignálok

A Unix rendszer a folyamatok vezérlését a folyamatoknak küldött ún. szignálok (signals) segítségével végzi: a ^Z billentyű például egy STOP szignált küld az előtérben futó processznek. Processzt kiölni szintén szignál(ok) segítségével lehet: az előtérben futó program a ^C (Ctrl-c) megnyomására egy INT szignált kap, amely rendszerint a program elhalálozását vonja maga után. Háttérben futó folyamatainkat a "kill" paranccsal irthatjuk ki: alapértelmezés szerint a "kill" egy TERM (terminate) szignált küld a megadott folyamatnak:
claudius:~$ sleep 60 &
[1] 332
claudius:~$ ps
  PID TTY STAT  TIME COMMAND
  310 pp0 S     0:00 -bash
  332 pp0 S     0:00 sleep 60
  333 pp0 R     0:00 ps
claudius:~$ kill %1
claudius:~$ ps
  PID TTY STAT  TIME COMMAND
  310 pp0 S     0:00 -bash
  334 pp0 R     0:00 ps
[1]+  Terminated              sleep 60
A "sleep" utasítás egyébként várakozik a megadott számú másodpercig ("elaltatja" a folyamatot). A "kill %1" helyett természetesen írhattunk volna "kill 332"-t is.

Ha más (nem TERM) szignált akarunk küldeni, a kill parancsot megfelelően paraméterezni kell, például a STOP szignálhoz: "kill -STOP pid". Ennek ugyanolyan hatása van, mintha az a folyamat az előtérben futna, és a ^Z-t nyomtuk volna meg: a folyamat felfüggesztett állapotba kerül. Folyamatot megölni még a HUP (hangup) és a KILL szignálokkal is lehet. (Az előbb látott nohup parancs ezen HUP szignál ellen teszi immunissá a folyamatot.) A sokféle látszólag azonos hatású szignál oka, hogy korántsem azonos hatásúak: például a HUP és a TERM szignálokat a folyamat felülbírálhatja, saját szignál-kezelő rutint állíthat be (így van ez az INT szignálnál is). Ezeket a szignálokat a folyamat kapja meg, és alapértelmezés szerinti kezelő rutinjuk lép ki. A KILL szignál hatására viszont a kernel öli meg a folyamatot, annak megkérdezése nélkül. Ezért nem probléma Unixban, ha egy folyamat "lefagy", végtelen ciklusba kerül: egy KILL szignál mindig megoldja a problémát.

Szignált csak saját processzeinknek küldhetünk (kivéve a root-ot, aki bármely processzel rendelkezhet). Az eddig felsoroltakon kívül még számos egyéb szignál van, megemlítjük még az ALARM szignált: a rendszert megkérhetjük, hogy megadott idő múlva küldjön egyet. Ezt használják időzítési célokra, többek között a "sleep" utasítás is így működik. De szignálokat használ a rendszer sok más egyéb, a folyamatot érintő rendszerinformáció közlésére is, de ezek főleg programozók számára érdekesek.

3.10.5. Folyamatok prioritása, a nice parancs

Már korábban szó volt a folyamatok prioritásáról (egy folyamat prioritását megnézni legegyszerűbben a "top" paranccsal lehet, vagy a "ps" parancs -l opciójával a PRI oszlopban). Ez a prioritás (szokás még ütemezési - scheduling - prioritásnak is nevezni) azt szabja meg, hogy ha több folyamat is van egyszerre futóképes állapotban (több folyamat verseng az egyetlen CPU erőforrásért), akkor a kernel milyen arányban ossza meg a rendelkezésre álló CPU időt az egyes processzek között. Unixban a prioritás számszerű értéke minél kisebb, annál több CPU időt fog kapni a folyamat. Prioritás értéke negatív is lehet: negatívabb érték magasabb prioritást jelent.

Minden folyamat három prioritással rendelkezik: egy alapprioritással (base priority), amely állandó, egy ütemezési prioritással (sceduling priority), amely a program futásakor nő, és egy ún. "nice" prioritással, amely (bizonyos határok között) felhasználó által változtatható. Ütemezéskor e három érték bizonyos szabályok szerint képzett összegét használja a rendszer: az ütemező algoritmus döntési pontján mindig a legalacsonyabb összeggel rendelkező processz kapja meg a vezérlést (ezért kell ebbe az összegbe az elhasznált CPU idővel növekvő tagot is tenni: egyébként mindig csak a legmagasabb prioritású folyamat futna). A "nice - n novekmeny parancs" szolgál arra, hogy a "parancs"-ot a megnövelt nice prioritás értékkel futtassuk. (Vagyis effektíve a folyamat prioritását csökkentsük). Erre akkor lehet szükség, ha valami számításigényes, hosszan futó programot indítunk, de nem akarjuk jelentősen lassítani az interaktívan dolgozók munkáját. Ezt a "nice" értéket egyébként a "top" "r" parancsával is megváltoztathatjuk. Nem privilegizált felhasználó csak növelni tudja folyamatai nice értékét (illetve a visszacsökkentéskor nem tudja az induló érték alá csökkenteni), a root tetszőlegesen állíthat prioritást.

3.11. Érintkezés más felhasználókkal

3.11.1. A többi felhasználó

Azt, hogy jelenleg kik használják rendszerünket, a "who " paranccsal kérdezhetjük le:
claudius:~$ who
tiv      ttyp2    Jul 21 14:37 (euromath.vma.bme)
Ami azt mutatja, hogy a "tiv" nevű felhasználó, a 2-es sorszámú pszeudo- terminálon dolgozik, a bejelentkezés időpontja látható még, illetve az, hogy (pszeudo-terminálról lévén szó) a bejelentkezés hálózaton keresztül történt, és hogy mi a távoli állomás neve. Látható az is, hogy "tiv" jelenleg az egyetlen felhasználó.

Ennél bővebb információt kaphatunk a "w" paranccsal:

claudius:~$ w
  4:19pm  up  6:09,  1 user,  load average: 0.00, 0.00, 0.00
User     tty      from             login@  idle   JCPU   PCPU  what
tiv      ttyp2    euromath.vma.bme 2:37pm                      w
Ahol a legelső sorban az egész rendszerre vonatkozó információk láthatók, a felhasználóról szóló sorokban pedig az, ami a "who "-nál is látszott, kiegészítve azzal, hogy mennyi ideje nem nyúlt az illető a billentyűzethez (idle time), illetve hogy mennyire CPU igényes munkát folytat (JCPU, PCPU), valamint hogy mely parancsot futtatja éppen (what mező). Még egy hasznos parancs: a "last". Ezzel a paranccsal megnézhetjük a bejelentkezéseket időben visszafelé haladva, illetve argumentumként egy user-nevet megadva csak annak a felhasználónak a bejelentkezéseit. Opcióként azt adhatjuk meg, hogy a hány adatra vagyunk kíváncsiak: a "last -1 user_nev" megadja az adott felhasználó utolsó bejelentkezésének dátumát, azt hogy melyik terminálról jelentkezett be, illetve hogy mennyi időt töltött bejelentkezve.

3.11.2. Kommunikáció a többiekkel: write, talk, mail

Az éppen bejelentkezett felhasználóknak a "write" paranccsal küldhetünk rövid üzenetet: "write [tty] user_nev" után gépelhetjük az üzenetünket, (ha a partner időközben válaszol, az is megjelenik), majd ^D-vel fejezhetjük be. A terminál azonosító megadására akkor van szükség, ha a keresett felhasználó több példányban is be van jelentkezve a rendszerre. (Ez egy grafikus-ablakozós környezetben mint az X Windows könnyen megtörténhet.) Ha nem akarjuk, hogy mások nekünk üzenetet küldjenek, a "mesg n" üzenet használjuk. Üzenetek fogadásának újraengedélyezéséhez használjuk a "mesg y" parancsot. Mivel a "write" utasítás úgy működik, hogy üzenetünket a másik felhasználó terminálját reprezentáló file-ba írja, ezek az utasítások tulajdonképpen ennek a speciális file-nak a hozzáférési jogosultságait állítják.

Kulturáltabb kommunikációs lehetőséget jelent a "talk" program: a "talk user_nev [tty]" paranccsal. Erre a felhívott félnek válaszolnia kell (szintén a "talk" paranccsal, csak az user_nev helyébe a hivó nevét írva). A kapcsolat megteremtése után a "talk" program kettéosztja a képernyőt: a felső részben azt láthatjuk amit mi gépelünk, az alsó részben pedig azt amit beszélgetőpartnerünk. Hasznos billentyűk: ^L -lel újrafrissíthetjük a képernyő tartalmát (ha valamilyen más program beleírása miatt összevzavarodna), és beszélgetés végén (természetesen az illő búcsúzkodás után) a ^C-vel léphetünk ki. A "mesg" parancs hatása a "talk"-ra is érvényes.

Nem interaktív üzenetet a "mail" paranccsal hagyhatunk valakinek: ennek legegyszerűbb módja a "mail user_nev" parancs: ekkor a "Subject:" kérdésre írjuk be levelünk tárgyát, majd gépeljük be a levelet! Befejezni egy, csak a . karaktert tartalmazó sorral lehet. Az utána megjelenő "Cc:" (Carbon Copy) kérdésre további címeket (felhasználó neveket) adhatunk meg, akik a levélből másolatot kapnak. Ha 'Enter'-t ütünk, a levelet csak az első címzett (akit a "mail" után írtunk) kapja meg.

Ha levelünk érkezett, ezt a rendszer rögtön bejelentkezéskor kiírja: a "You have mail.", vagy "You have new mail." üzenetek valamelyikével, illetve bejelentkezés után a shell is folyamatosan ellenőrzi, hogy érkezett-e új levél, és kiírja ha érkezett. Leveleinket elolvasni szintén a "mail" programmal lehet:

claudius:~$ mail
Mail version 5.5 6/1/90.  Type ? for help.
"/var/spool/mail/tiv": 1 message
>   1 VARKONYI@bme-eik.eik  Thu Jul 20 09:03  40/1996  "DECnet routing"
&
Itt a látható, hogy jelen pillanatban 1 levelünk van: az első mező a levél sorszáma, a második feladó neve, a levél dátuma, majd a sor végén a levél tárgya (subject) jelenik meg. Levelet elolvasni a "mail" program & promptja után írt levélsorszámmal lehet, törölni pedig a "d levelsorszam" paranccsal. Kilépni a "mail" programból a "q" paranccsal lehet. Lehetőség van továbbá a levél file-ba vagy ún. "mail-folder"-be (levél dosszié) mentésére a "s file_nev" paranccsal. Levelek fogadását letiltani nem lehet.

A gyakorlatban ritkán használjál levelezésre a "mail" programot: a legtöbb rendszeren sokkal kényemesebben használható (teljesképernyős menüvezérelt, állítható szövegszerkesztős) levelzőprogramok is vannak (például az "elm" vagy a "pine") - ezek ismertetésére sajnos terjedelmi okból nincs lehetőségünk.

3.11.3. Hálózatban

Amennyiben gépünk része az Internet hálózatnak, illetve IP (Internet protocol) típusú hálózatba van kötve más gépekkel, ez utóbbi két paranccsal (talk, mail) más gépek felhasználóival is kommunikálhatunk: csupán user-név helyett a user_nev@internet.gep.cim formátumú címet kell megadnunk. Hálózatban másik gépre bejelentkezni a "telnet gep_nev" paranncsal lehet: a "telnet" a hálózati teminál szoftver. Sajnos a halózati (Internet) szolgáltatások részletes ismertetésére itt nincs bővebb lehetőségem.

3.12. Adatok a rendszer egészéről

Már láttuk, hogy (például a "top", vagy a "w" parancsokkal) adatokat kaphatunk a rendszer egészéről: nézzük most ezeket meg részletesebben! Például a "top" egy kimenetének felső pár sora:
 10:38am  up 1 day, 27 min,  1 user,  load average: 0.00, 0.00, 0.00
20 processes: 19 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  1.3% user,  1.1% system,  0.0% nice, 97.6% idle
Mem:  15176K av, 13484K used,  1692K free,  4484K shrd,  8888K buff
Swap: 16392K av,     0K used, 16392K free
A legfelső sorban az idő, aztán a gép ún. uptime értéke (mennyi idő telt el reboot óta), a bejelentkezett felhasználók száma, illetve a három "load average" (átlag terhelés) látható. Ezek jelentése: átlagosan hány futóképes (CPU-t igénylő) folyamat tartózkodik az ütemezőben. A három érték közül az első az utolsó pár (általában 5) másodpercre vonatkoztatott terhelésátlag, a középső az elmúlt pár percre vonatkozik, a harmadik pedig az elmúlt fél órára vetített átlag. Jelen esetben mindhárom érték nulla: a gépen egy felhasználó dolgozik csak, aki leginkább csak a shell-t futtatja: a rendszer ideje legnagyobb részében várakozik.

A következő sorban processz-statisztikát láthatjuk: a rendszeren jelenleg 20 folyamat fut, ebből 19 "alszik" (sleeping - várakozik valamilyen eseményre, általában inputra), 1 fut (running - jelen esetben ez a "top"), 0 zombie (zombie-nek a már halott, de még a rendszerből el nem tűnt folyamatokat nevezik: akkor lehetséges ez, ha a gyermek folyamat már kilépett, de a szülő még nem fogadta a gyermek visszatérési értékét - még nem vett tudomást gyermeke haláláról), illetve 0 darab STOP szignállal megállított folyamat van.

A következő sorban (CPU states) a processzor kihasználtságot olvashatjuk le: idejének 1.3%-át tölti a processzor felhasználói folyamatok futtatásával, 1.1%-ot fut a kernel (rendszerfeladatok), 0%-ban foglalkozik csökkentett prioritású folyamatokkal, és idejének 97.6%-át henyéléssel tölti (idle). Ezt az információt (CPU használat statisztika) egyébként a "time" paranccsal kaphatjuk meg egyes programokra: a "time parancs" utasítás először lefuttatja az utasítást, majd sokféle rendszer-statisztikát közöl a futtatásról.

Az utolsó előtti sorban a fizikai memória kihasználtságát láthatjuk: av: összes rendelkezésre álló (itt nem számolja bele a kernel és a rendszeradatok által elfoglaltat), used: használt, free: szabad, shrd: a memóriában lévő osztott könyvtárak (shared libraries) által elfoglalt terület, és buff: a buffer cache aktuális mérete. Az utolsó sorban pedig a virtuális memória adatai vannak: mennyi swap memóriával rendelkezik a rendszer, és ebből mennyi szabad még. Ezeket a (memória foglaltsági) információkat egyébként még a "free" paranccsal is megkaphatjuk.

3.13. Linux specialitások

3.13.1. A virtuális konzol (virtual console)

Azon a problémán, hogy egy géphez csak egy monitor és egy billentyűzet tartozik, úgy próbál a Linux segíteni, hogy több ún. virtuális konzolt használhatunk, amelyek mindegyike úgy viselkedik, mintha a rendszer konzol terminálja lenne. A virtuális konzolok számát a rendszergazda konfigurálhatja, közöttük a bal Alt+funkcióbillentyűkkel illetve a bal Alt + jobbra/balra nyíl billentyűkkel válthatunk.

3.13.2. Speciális billentyűzetkombinációk

Nagyon hasznos funkció a Shift+PageUp/PageDown, amellyel - virtuális konzolon - pár oldalnyi szöveget görgethetünk oda-vissza. Az éppen futó processzt a "Print Screen" megnyomásával is kilőhetjük, ha az esetleg a ^C-re nem reagálna. Az operációs rendszert újraindíthatjuk a jól ismert Ctrl-Alt-Del kombinációval (természetesen csak konzolról!) - ezt "shutdown" procedúraként, a gép kikapcsolása előtt is használhatjuk, ugyanis gondosokdik a bufferek diszkre írásáról, a folyamatok kultúrált lezárásáról stb.

Tovább...