Obcování s ďáblem 8: Jak se do shellu volá, tak se program ozývá - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Seriály

Více seriálů



Software

Obcování s ďáblem 8: Jak se do shellu volá, tak se program ozývá

13. září 2001, 00.00 | Možná vás překvapí, že spouštět programy už vlastně umíme - od začátku vlastně neděláme nic jiného!

Obcování s ďáblem 8: Jak se do shellu volá, tak se program ozývá

Možná vás překvapí, že spouštět programy už vlastně umíme — od začátku vlastně neděláme nic jiného! Všechny "příkazy", o kterých jsme se zatím bavili (s jedinou výjimkou, jíž jsou příkazy cd/pushd/popd), jsou totiž ve skutečnosti programy, jež shell pouze volá.

Příkazy jsou programy, najdeme je na disku

Chceme-li se o tom přesvědčit, můžeme použít příkaz whereis, který nám řekne, ve kterém souboru na disku je uložen program odpovídající zadanému jménu:

240 /tmp> whereis ls
/bin/ls
241 /tmp> whereis cp
/bin/cp
242 /tmp> whereis grep
/usr/bin/grep
243 /tmp> whereis locate
/usr/bin/locate
244 /tmp> whereis pwd
/bin/pwd
245 /tmp> whereis whereis
/usr/bin/whereis
246 /tmp> whereis cd
247 /tmp> 

(Poslední příklad potvrzuje, že cd není program, ale příkaz interpretovaný shellem: whereis jej nemůže najít.)

Stačí zapsat cestu...

Libovolný program můžeme spustit tak, že prostě napíšeme do příkazového řádku shellu jméno souboru, ve kterém je program uložen — i s cestou. Ta může být jak absolutní, tak i relativní (pro příklad použijeme jednoduchoučký program date, který prostě vypíše momentální datum a čas):

257 /tmp> whereis date
/bin/date
258 /tmp> /bin/date
Sat Aug 25 17:03:25 CEST 2001
259 /tmp> mkdir -p a/b/c
260 /tmp> cp /bin/date a/b/c/kopieDate
261 /tmp> /tmp/a/b/c/kopieDate
Sat Aug 25 17:04:29 CEST 2001
262 /tmp> a/b/c/kopieDate
Sat Aug 25 17:05:01 CEST 2001
263 /tmp> 

Ovšem, je zde jedna na první pohled prapodivná věc: pokud bychom si chtěli ušetřit i tu kratičkou relativní cestu, program zavolat nepůjde!

284 /tmp> cd a/b/c 
285 a/b/c> ls -l kopieDate
-r-xr-xr-x  1 ocs  wheel  13884 Aug 25 17:04 kopieDate*
286 a/b/c> kopieDate
zsh: command not found: kopieDate
287 a/b/c> 

To je proto, že zadáme-li jméno programu bez cesty, shell se nedívá do aktuální složky; namísto toho prohledává standardní příkazové složky. Díky tomu jsme také klidně mohli psát rovnou "ls" namísto "/bin/ls" a podobně.

Těm, kdo si ještě pamatují "záhadu" z čtvrtého dílu, kdy jsme vyrobili ukázkový program v C a spustili jsme jej příkazem "./a.out", můžeme dnes dát odpověď: překladač jazyka C ukládá standardně hotový program do souboru jménem "a.out" v aktuální složce. Jelikož však pro spuštění programu, který není ve standardních příkazových složkách, musíme zadat nějakou cestu, vypomohli jsme si tečkou; to, že tečka vždy reprezentuje aktuální složku, už víme z popisu příkazu mv.

Standardní příkazové složky

Je to sice hezké, že shell dokáže hledat příkaz, který jsme zapsali bez cesty, v nějakých standardních složkách; které to ale jsou, a jak jejich seznam měnit?

Přístup k seznamu příkazových složek (přesněji řečeno, k proměnným shellu obecně) je jednou z mála věcí, jež jsou v různých shellech řešeny jinak. Nejprve se proto podíváme na řešení v zsh, který používám nejraději a ve kterém je proto většina příkladů:

Shell zsh udržuje seznam standardních příkazových složek v proměnné PATH. Její obsah si můžeme zobrazit pomocí již známého příkazu echo, a jedné nové finty shellu: pokud zapíšeme do příkazového řádku znak '$' a za něj jméno proměnné, shell celou tuto konstrukci nahradí obsahem proměnné:

291 a/b/c> echo $PATH
/usr/bin:/bin:/Local/Users/ocs/Apps:/Network/Applications:/System/Applications:/usr/local/bin
292 a/b/c> 

Vidíme, že seznam (u vás bude asi trochu jiný, já tento příklad připravuji v Mac OS X Serveru) obsahuje prostě jména složek, oddělených dvojtečkami. Hledá-li shell nějaký příkaz, prostě se nejprve podívá do složky "/usr/bin", pak do složky "/bin", a tak dále; jako poslední vyzkouší složku "/usr/local/bin", a pokud příkaz nenajde ani tam, ohlásí chybu.

Chceme-li některou proměnnou v zsh změnit, prostě napíšeme její jméno, znak '=', a požadovanou hodnotu. Samozřejmě, že i zde můžeme využít výše popsanou fintu se znakem '$'; pro přidávání nové složky k dosavadnímu obsahu proměnné je to velmi šikovné:

291 a/b/c> echo $PATH
/usr/bin:/bin:/Local/Users/ocs/Apps:/Network/Applications:/System/Applications:/usr/local/bin
292 a/b/c> PATH=$PATH:/tmp/a/b/c
293 a/b/c> kopieDate
Sat Aug 25 18:11:11 CEST 2001
294 a/b/c> cd 
295 ~> kopieDate
Sat Aug 25 18:11:20 CEST 2001
296 ~>           

Jak je vidět, shell ihned začne nový obsah proměnné PATH používat, takže náš program "kopieDate" se ve složce "/tmp/a/b/c" najde kdykoli zadáme jeho jméno bez cesty.

Nakonec stojí za to si říci kde se vlastně "proměnné shellu" ukládají, a jak dlouhou platnost má taková změna, jakou jsme právě provedli. Odpovědi jsou "vlastně nikde" — proměnné jsou uloženy jen v operační paměti běžícího shellu — a už zřejmý důsledek "jen v rámci shellu, ve kterém jsme změnu provedli, a jen dokud jej neukončíme".

V tcsh je situace velmi podobná; pro nastavení proměnné PATH však musíme použít příkaz setenv, jehož prvním argumentem je jméno proměnné a druhým požadovaná hodnota; navíc musíme před dvojtečkou použít obrácené lomítko, protože tcsh by se ji jinak snažil interpretovat speciálním způsobem, a ohlásil by chybu (připomeňme si podobné použití obráceného lomítka ve třetím dílu, když jsme chtěli použít jméno souboru obsahující mezeru):

296 ~> tcsh
[g4:~] ocs% kopieDate
kopieDate: Command not found.
[g4:~] ocs% echo $PATH
/usr/bin:/bin:/Local/Users/ocs/Apps:/Network/Applications:/System/Applications:/usr/local/bin
[g4:~] ocs% setenv PATH $PATH\:/tmp/a/b/c
[g4:~] ocs% kopieDate
Sat Aug 25 18:44:12 CEST 2001
[g4:~] ocs% 

Jak je to vlastně s těmi shelly?

A na závěr ještě jednu informaci, kterou si už pozornější čtenáři jistě domysleli sami: shelly samy nejsou ničím jiným, než programy; možnost "přepínání shellů prostým zapsáním jejich jména", s níž jsme se seznámili hned ve druhém dílu, tedy vlastně nic nepřepíná, jen spouští nové programy. Spuštěný shell prostě vypíše svůj "prompt" a začne s námi komunikovat.

To samozřejmě znamená, že ve skutečnosti "běží" více shellů najednou: ty "starší" jen čekají, až program, který spustily — tj. novější shell — skončí. Ten "nejmladší" s námi komunikuje. Pokud tedy nyní např. "přepneme" na sh a na zsh:

[g4:~] ocs% sh
$ zsh
1 ~> 

běží ve skutečnosti shelly čtyři: náš "původní" zsh, v něm tcsh, do kterého jsme přepnuli na řádku 296, v něm sh a v něm další zsh. Ono se dohromady nic nestane, budeme-li shelly takhle "hromadit" na sebe — stojí to jen trochu paměti, a té je k dispozici spousta. Chceme-li však být slušní a "vnořené" shelly ukončit, stačí stisknout kombinaci Control-D. Shell, který s námi právě komunikuje, okamžitě skončí (tcsh navíc vypíše "exit", sh se naopak neobtěžuje ani přejít na nový řádek), a vidíme prompt shellu "předchozího":

1 ~> ^D
$ ^D [g4:~] ocs% ^D exit
297 ~> 

("^D", ukazující, kde bylo stisknuto Control-D, jsem do výpisu přidal ručně — shell jej nezobrazí. Povšimněte si také čísla řádky (297), které potvrzuje, že jsme se skutečně znovu vrátili do našeho "původního" zsh.)

A co příště?

Příště zůstaneme u spouštění programů. Protože OS X je plně multitaskový systém, můžeme také spouštět více programů najednou — ukážeme si jak na to. Ukážeme si i další finty!

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Software  

 

 

 

Nejčtenější články
Nejlépe hodnocené články
Apple kurzy

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: