Unix-rendszerhéj

A Unix operációs rendszerben különféle parancssori értelmezők működnek, melyeket rendszerhéjnak vagy angolul shellnek nevezünk. Ez a rendszerhéj az összekötő kapocs a rendszer magját képező kernel és a felhasználó között. Az asztali rendszereken ezeket többnyire grafikus felületek egészítik ki. A shellből (konzolról) vezérelt gépek előnye, hogy jóval kisebb erőforrásigényűek a grafikus felületeknél. A grafikus felhasználói felületek (GUI) ugyanis egyrészt újabb réteget képeznek a rendszermag és a felhasználó között, másrészt erőforrásigényük többnyire magas. Ennek következtében a shellből (konzolról) vezérelt rendszerek stabilabbak, és gyorsabbak, így teherbírásuk miatt napjainkban főleg Unix alapú kiszolgálókon népszerűek.

Unix-típusú rendszerek alatt a felhasználó több rendszerhéj között is választhat, melyek mindegyike rendelkezik egyedi tulajdonságokkal, melyek segítségével bizonyos feladatok könnyebben elvégezhetőek, mint más rendszerhéjakkal. A számítógépbe történő bejelentkezés után a rendszerhéj indítja el az operációs rendszernek nélkülözhetetlen folyamatokat és automatikusan induló programokat.

A shell programozható az úgynevezett shellscriptek segítségével. Ez egy speciális parancsnyelv, mely az operációs rendszer által értelmezhető utasításokat tartalmaz, így a klasszikus értelemben vett programozási nyelvektől eltérően nincs szükség a kód lefordítására és linkelésére.

A Unix-rendszerhéjak kialakulása
Steven Bourne, az AT&T / Bell Laboratories egyik munkatársa az elsők között fejlesztett ki parancsértelmező rendszerhéjat a Unix operációs rendszerekhez még a '60-as, '70-es években. A Bourne Shell nevét alkotójáról kapta, és ez lett az első széles körben elterjedő rendszerhéj, mely új formájában (Bourne Again Shell) ma is népszerű.

Mikor a University of California at Berkeley is bekapcsolódott a Unix fejlesztésébe, új színfoltot hoztak a shellek világába: Bill Joy programozó vezetése alatt megalkották a saját, Bourne Shellhez képest számos kényelmi funkcióval és C-nyelvhez hasonlatos szintaktikájú parancsértelmezőjükkel ellátott megoldásukat, a C Shellt. Egy anekdota szerint nevét a „sea shell” (tengeri kagyló) szójátékból kapta. A C Shell fejlesztése az 1970-es évek végén új erőre kapott, ennek eredménye lett a TENEX C Shell, amelyet főképp Ken Greernek és Paul Place Waynnek köszönhetünk.

Az 1980-as évek derekán David Korn vezetésével a Bell Laboratories továbblépett a Bourne Shellen, megalkotva a korn Shellt. Ez volt a Unix System V ágának első modern shellje. Ennek a rendszerhéjnak készült egy a nagyközönség számára is ingyenesen használható változata, a Public Domain Korn Shell. Később a Free Software Foundation (Szabad Szoftver Alapítvány) megalakulása, a GNU licencelés új héjprogramot hívott életre, a Bourne Again Shellt. Ez a megoldás nem más, mint az egykori ős-Bourne Shell GPL-licencelésű, továbbfejlesztett változata, amelyet ma már az első számú linuxos shellként tartanak számon, a 2010-es években futtató shellként ennek komoly vetélytársa lett a dash - mely a szabvány - ISO 9945 - shell közelibb magvalósítása.

A shell általános képességei
Minden Unix-alapú rendszerben lehetséges:
 saját parancsok kivitelezése
 „wildcard”-ok (speciális illesztések) használata fájlnevekben: *, ?
 héjprogramok ("szkript"-ek) végrehajtása
 feltételes kifejezések (if, case) és ciklusok (while, for) alkalmazása
 beépített parancsok használata (cd, read)
 pszeudo-parancsok létrehozása (alias)
 belső változók használata
 a környezet manipulálása új folyamatok indítása előtt
 bemenet és kimenet átirányítása
 több folyamat indítása, ezek adatcseréje csöveken (pipe) keresztül
 folyamatok indítása a háttérben
 a jelentkezési karakter definiálása (prompt)
 külső parancsok keresési sorrendjének megadása

A modernebb rendszerhéjak ezen felül még az alábbi tulajdonságokkal is rendelkeznek:
 parancssorszerkesztés (command line editing) és kiegészítés (completion)
 korábbi parancsok visszakeresése és szerkesztése (command history)
 folyamatok megállítása és újraindítása (Job Control)
 számítási feladatok elvégzése (expr)
 állománytulajdonságok tesztelése (test)
 jelzések (signal) küldése (kill) és fogadása (trap)
 más folyamat bevárása (wait)

Egy parancs leállítása esetén a rendszerhéj a billentyűzet-meghajtót is használja. CTRL-C a parancs leállítását vonja maga után, és ezt a billentyűzet-meghajtó indítja el.

Működése 
Az operációs rendszerek működtetése közben a felhasználó és a gép közötti kommunikáció valamilyen terminálon (esetleg virtuális, vagy emulált környezeten) keresztül történik. Ennek egyik eszköze a shell is, melyen keresztül a vezérlés szöveges karakterekre korlátozódik. A vezérlő jelsorok elsődleges beviteli eszköze (standard input, vagy röviden STDIN) a használt terminál billentyűzete. Minden egyes billentyű lenyomásakor annak kódját a shell megkapja és egy pufferben tárolja, amelynek tartalmát többnyire szerkeszteni is lehet. A parancssor ezen szolgáltatását sorszerkesztőnek, vagy promptnak nevezzük. A sorszerkesztővel többnyire egyszerű műveleteket – törlést, felülírást, beszúrást – végezhetünk a kurzormozgató billentyűk segítségével. Ezt követően a bevitt jelsor megjelenik a terminálon. Egy érvényesítő végjellel (alapértelmezésként ez az ENTER vagy RETURN billentyű) lehet a parancsot értelmeztetni.

Ilyenkor a puffer tartalmát megkapja a shell értelmező (interpreter) része, amely szétbontja utasításokra és paraméterekre. Az utasítások között elsőbbségek, precedenciák lehetnek, azaz nem feltétlenül beviteli sorrendben lesznek elindítva. Végrehajtás
során, ha szintaktikailag helyes az utasítássor, akkor a shell először helyettesítő névként (alias), ha nincs ilyen, akkor a beépített parancskészletében (builtin) keresi meg a parancshoz tartozó cselekvéssort. Ha ilyen nem létezik, akkor egy alkalmazás neveként értelmezi, és megkísérli elindítani. A beépített parancsok a shellbe vannak integrálva, így működésében olyan, mintha egy programfájl kerülne végrehajtásra, azzal a különbséggel, hogy nem különálló részként található meg a fájlrendszeren. Egyes shellekben
lehetőség nyílik a korábban kiadott parancsok tárolására, újbóli kiadására. Ezeket a parancsokat összefoglaló néven előzményeknek (history) nevezzük, az őket tartalmazófájl pedig az előzményfájl, mely általában rejtett, és a shellt futtató felhasználó saját könyvtárában, vagy bizonyos esetekben a shell saját programkönyvtárában, vagy ritkábban a gyökérkönyvtárban található.

Többnyire elmondható, hogy a végrehajtás szekvenciális, azaz egy újabb utasítás csak akkor adható ki, ha már egy korábbi lefutott. Ez igen nagy megkötés, ennek áthidalására szolgál a munkavezérlés, amellyel megtehetjük, hogy bizonyos parancsokat háttérben futtassunk külön folyamatként, vagy felfüggesszük. A felfüggesztett folyamatoktól a rendszer elveszi a CPU vezérlést, ha szükséges, a lefoglalt memóriájukat elsők között írja ki a lapozó (swap) partícióra.

Shell szkript 
A shell szkript olyan számítógépes program, melyet arra terveztek, hogy egy szabvány shell implementáció futtassa. Legtöbbször önállóan futtatható fájlokban tároljuk őket. Az alábbi példa egy kutyát mozgat a képernyőn:

#!/bin/sh
#         ))__       __((
#         |__/       \__|
# )__))             ((__(
# /|    |)              (|     |\

while :; do
a="         ))__\f\e[13D         |__/\f\e[12D )_))\f\e[10D /|    |)";
printf "\e[10;1;f\e[?25l"; c=0; while [ $c -le 43 ]; do printf "$a\e[3A\e[9D ";
sleep 0.018; c=$((c+1)); done; # balra
a="__((        \f\e[13D\\__|         \f\e[10D((__( \f\e[10D(|     |\\";
while [ $c -ge 1 ]; do printf "$a \e[3A\e[13D";
sleep 0.018; c=$((c-1)); done;
printf "\e[4B\r\e[?25h"; done;

Irodalom
 Fehér János: Héjprogramok, Linux alatti parancsértelmezők 1.0
 Helmut Herold: Linux-Unix-Shells, Bourne-Shell, Korn-Shell, C-Shell, bash, tcsh 
 Alexander Mayer: Shell-Programmierung in Unix

Kapcsolódó lapok 
 bash

Unix