Další Předchozí Obsah

7. Shelly UNIXu

7.1 Co je to shell?

Shell je prostředek komunikace uživatele s operačním systémem. Historicky prvním a dodnes nejdůležitějším je Bourne shell, pojmenovaný po svém autorovi A. S. Bourne, který jej navrhl a naprogramoval na přelomu 60. a 70. let. Principy Bourne shell přejaly všechny následující příkazové interprety, obvykle jde pouze o jiný uživatelský přístup.

UNIX je interaktivní operační systém, podporuje zejména sezení uživatele u terminálu. Je to od chodu systému neoddělitelný víceuživatelský stav systému, kdy všechny výpočetnímu systému známé terminály jsou dostupné pro komunikaci s uživatelem. Při vstupu systému do víceuživatelského režimu podle tabulky připojených terminálů je pro každý terminál procesem init (proces s PID=1) startován proces nazývaný getty, který na obrazovku terminálu vypisuje oznámení o připojení k systému, výzvu k přihlášení se. Je to řetězec login:, kterému obvykle předchází jméno konkrétní instalace UNIXu pro odlišení v rámci sítí.

Pokud uživatel napsal správně svoje jméno i heslo, operační systém jej registruje jako přihlášeného, proces login startuje komunikaci pomocí příkazového interpretu Bourne shell.

Proces init jako otec všech procesů v systému vytváří procesy getty, jejichž počet odpovídá logicky existujícím periferiím, přes které uživatel vstupuje do systému; každý getty přepisuje sám sebe (mechanizmem exec) na proces login, a ten následovně opět pomocí exec na proces sh (shell). Ukončí-li uživatel komunikaci (klávesou Ctrl-d), končí činnost procesu sh, proces init tuto skutečnost registruje a vytváří nový proces getty (pomocí fork a pak teprve exec), který vypíše na obrazovku řetězec končící na login:.

Jako výsledný proces v úvodní sekvenci je sh, shell, příkazový interpret. Může jím být i jiný libovolný program např. sběru dat. Jaký program je uživateli po přihlášení pro komunikaci spuštěn, je jednoznačně spojeno se jménem uživatele. V daném okamžiku je v tabulce evidovaných uživatelů oprávněných přihlásit se do systému v souboru /etc/passwd s jedním jménem spojen pouze jeden příkazový interpret. Záměnou jména programu v této tabulce lze dosáhnout jiné komunikace uživatele se systémem.

7.2 sh, csh, tcsh, ksh, bash

Nejznámějšími variantami shellu jsou (řazeny dle data vzniku):

7.3 C-shell - rozšíření Bourne shellu

Vzhledem k nedostatkům Bourne shell vzniklo v průběhu vývoje operačního systému UNIX několik dalších příkazových interpretů. Na začátku 80. let na kalifornské škole University of California v Berkeley student William Joy vytvořil interpret, který nazval C-shell. Hlavní myšlenkou byla snaha vytvořit způsob komunikace s operačním systémem velmi podobný jazyku C (odtud i název). Myšlenka usnadnit uživateli komunikaci byla jistě dobrá, ale se změnou synatxe způsobila nepřenositelnost scénářů z Bourne shell.

Avšak C-shell nejen připodobnil zápis řídících struktur jazyku C, zavedl numerické proměnné a proměnné typu pole textových řetězců atd., ale pokusil se odstranit i jiné problémy, které Bourne shell neřešil.

Zamezení přepisu existujících souborů

Přesměrování > v Bourne shellu na obyčejný soubor znamená vytvoření tohoto souboru, a pokud soubor existuje, jeho zkrácení má nulovou délku a poté naplnění standardním výstupem. Každému takovému nebo jakémukoliv jinému přepisu existujícího souboru přesměrováním můžeme v C-shell zabránit příkazem:

% set noclobber ;: znak vyzvy v C-shell je '%'

který vytvoří proměnnou se jménem noclobber. Takže

% who > kdo 
kdo : file exists. 
% who >> kdo ;: soubor je chranen i proti rozsireni 
kdo : file exists. 
% who >>! kdo ;: znak '!' za presmerovanim rusi ochranu 
% unset noclobber ;: rusi zamezeni prepisu 

Přesměrování

C-shell je rozšířen o přesměrování standardního chybového výstupu přidáním znaku &.

% cc program.c >& chyby

je zápis přesměrování standardního chybového výstupu překladače jazyka C do souboru chyby. Přitom je zápis ekvivalentní obdobě ... 2>&1, protože i zde je kanál 1 a 2 spojen. A analogicky platí pro >>& připojení ke standardnímu chybovému výpisu.

Řízení prací

Spustíte-li v Bourne shell proces nebo kolonu na příkazovém přádku v popředí, neovlivníte běh procesů jinak, než že je přerušíte z klávesnice. V C-shell, podobně jako v Job Control shell, je možné proces pozastavit a po chvíli obnovit chod procesu od místa pozastavení, a to buď na popředí nebo na pozadí. Pozastavení procesu běžícího na popředí dosáhne uživatel klávesou Ctrl-z. Pro pokračování v běhu slouží vnitřní příkazy bg (background, na pozadí) a fg (foreground, na popředí), přitom může být příkaz následován číslem práce. Práce (job) je příkaz nebo kolona.

Mechanizmus historie

Je uchování dříve použitých příkazových řádků. Je realizován vnitřním příkazem history. Proměnná stejného jména musí být nastavena na hodnotu odpovídající počtu posledních zapamatovaných řádků. Příkaz vypisuje seznam posledních (v našem případě dvaceti) dosud použitých příkazových řádků:

% set history = 20 
... 
% history 
10 who 
... 
18 ls -l 
19 pwd 
% 

kde v uvedeném výpisu je každý dříve použitý příkaz očíslován. Opakovat některý z příkazů lze pomocí znaku !:

% !128 
ls -l 

Mechanizmus záměn

Umožňuje definovat synonyma pro příkazový řádek. Vnitřní příkaz alias má formát

alias [ jmeno [definice] ]

a např.

% alias l "ls -l"

definuje nový příkaz se jménem l, přitom jeho obsah je dán definiční částí ls -l, kterou C-shell jméno nahradí a provede. Může se jednat i o sekvnci příkazů, protože jde o textovou substituci.

7.4 TC-shell - rozšíření C-shellu

TC-shell tcsh je zdokonalená verze Berkeley C-shellu. Chová se přesně stejně jako standardní C-shell, má však několik desítek nových příkazů, které výrazně zpříjemňují uživatelské prostředí. TC-shell je často označován jako C-shell s kompletací jmen souborů a editací příkazů. Nejpodstatnějšími změnami v porovnání s C-shellem jsou: Podrobnější informace lze získat příkazem man tcsh.

7.5 Proměnné v Bourne shellu

Proměnnou uživatel vytváří a současně definuje její obsah zadáním

$ jmeno=obsah 

kde jmeno je jméno proměnné a obsah je textový řetězec, kterým bude proměnná naplněna. Před a za operátorem "=" nesmějí být mezery. Obsah proměnné je textově substituován na místě, kde jménu proměnné předchází znak $:

$ echo $jmeno 
obsah

A může-li nastat kolize, je jméno proměnné uzavřeno mezi znaky { a }:

$ data=/usr/data 
$ echo $databaze ${data}baze 
informix /usr/databaze 

Obsah proměnné lze naplnit také standardním výstupem některého programu. V příkladu

$ dir=`pwd`

je proměnná dir naplněna textovým řetězcem, který za normálních okolností program pwd vypisuje na standardní výstup. Příkaz je uzavřen mezi znaky obráceného apostrofu ` `.

Obsah proměnné můžeme dále naplnit vstupem z klávesnice, to jest ze standardního vstupu, příkaz


$ read vstup 

očekává na následujícím řádku vstupu textový řetězec ukončený znakem nového řádku, kterým naplní obsah proměnné vstup. Proměnná vstup nemusela být dříve inicializována.

Vnitřním příkazem set můžeme získat seznam všech proměnných včetně výpisu jejich obsahu:


$ set 
HOME=/usr/jan 
IFS= 

MAIL=/usr/spool/mail/jan 
MAILCHECK=600 
PATH=/bin:/usr/bin:. 
PS1=$ 
PS2=> 
SHELL=/bin/sh 
TERM=ansi 
TZ=MET-1 
jmeno=obsah 
databaze=informix 
data=/usr/data 
dir=/usr/jan 
$

Z příkladu vidíme námi definované proměnné jmeno, databaze, data a dir na konci výpisu. Předchází jim seznam proměnných (jejichž jména jsou označena velkými písmeny), které jsme jako uživatelé nedefinovali, ale které byly definovány v okamžiku startu příkazového interpretu. Jejich význam je důležitý pro práci shellu a je následující:

Proměnná Její obsah
HOME domovský adresář,
IFS znak pro ukončení vstupu z klávesnice (je nastaven na znak nového řádku,
MAIL poštovní schránka elektronické pošty uživatele (viz příkaz mail(1)),
MAILCHECK časový interval, po jehož uplynutí shell hledá změnu v poštovní schránce,
MAILPATH seznam jmen souborů, dalších poštovních schránek uživatele,
PATH seznam cest k programům vnějších příkazů; standardně "/bin", "/usr/bin" a pracovní adresář,
PS1 výzva pro zápis příkazového řádku, 
PS2 druhá, pokračovací výzva; uživateli je nabídnuta, pokračuje-li příkaz na více řádcích; uživatel může explicitně stanovit následující řádek jako pokračovací znakem výluky '\' na místě před znakem nového řádku; PS2 bývá nastavena na "> ",
SHELL cesta k programu běžícího interpretu,
TERM typ terminálu,
TZ časová zóna, označení a relativita vzhledem k Greenwitch poledníku.

Proměnné, které už dále nebudeme potřebovat, lze zrušit vnitřním příkazem unset:


$ unset jmeno databaze data dir

Běžící proces řízený programem /bin/sh vytváří synovské procesy pro uspokojení požadavků uživatele. Synovské procesy pracují v rámci prostředí, kde jsou prováděny (prostředí uživatele), tj. jsou jim pro čtení dostupné obsahy proměnných shellu. Implicitně ale není dostupná žádná z nich, dostupnost je nastavována vnitřním příkazem export, např.

$ databaze=ingres 
$ export databaze 

stanovujeme viditelnost obsahu proměnné databaze v synovských procesech. Příkaz export bez argumentů vypíše seznam všech exportovaných proměnných.

Terminály

Všechny terminály jsou "skoro" ("softwarového"!) typu "vt100". To znamená, že vstupní klávesy jsou kódovány podle převodní tabulky uložené v souboru /etc/termcap.

Informace o nastavení některých speciálních kláves terminálu lze získat příkazem


$ stty -a

Týkají se pouze následujících funkcí:

erase, kill, werase, rprnt, flush, lnext, susp, intr, quit, stop, eof

Jestliže nám aktuální stav na daném terminálu nevyhovuje, můžeme v případě potřeby výše zmíněné funkce terminálu predefinovat a přiřadit jim jiné klávesy.

Implicitní hodnoty speciálních znaků se liší systém od systému. Nastavují se jako `name hodnota', kde jména jsou popsána níže a hodnoty mohou být zadány buď doslovně, nebo pomocí zápisu `^c' (stříška-znak), nebo jako celé číslo, které může začínat `0x' pokud je v šestnáctkové soustavě, `0' pokud je osmičkové soustavě nebo libovolnou jinou číslicí, pokud je v desítkové soustavě. Nastavením hodnoty `^-' nebo `undef' se příslušný speciální znak zakáže.

Předdefinovanou hodnotu -d, která odpovídá eof, lze změnit na znak [ příkazem


stty eof [

Novou klávesu pro backspace lze nadefinovat příkazem

stty erase vybraná_klávesa

7.6 Proměnné v C-shellu

Bourne shell C-shell
deklarace lokální proměnné jméno=hodnota set jméno=hodnota
deklarace globální proměnné setenv jméno hodnota
exportování proměnné export jméno
odkaz na proměnnou $jméno $jméno
seznam lokálních proměnných set set
seznam globálních proměnných export setenv
zrušení lokální proměnné unset jméno unset jméno
zrušení lokální proměnné unset jméno unsetenv jméno

7.7 Konfigurační soubory shellu

Každý shell využívá při svém startu jiné konfigurační soubory.

C Shell.cshrc a pak .login
Bourne Shell.profile
Korn Shell.profile a pak .kshrc
TC shell.tcshrc
Bourne Again Shell.profile a pak .bashrc


Další Předchozí Obsah