$PATH: Najděte správnou cestu

13. dubna 2015

Volně dostupný (open source) software se vždy vyznačuje poměrně pracnými přípravnými pracemi, než se ho podaří uvést do chodu a integrovat do stávajícího prostředí. I když se může zdát, že to odvádí pozornost od konečného cíle (řešit problémy pomocí instalovaných nástrojů), máte v procesu přípravy často příležitost zpříjemnit si práci s jedním z hlavních nástrojů naší branže: s příkazovým řádkem.

Režim příkazového řádku je pro mnohé lidi už svou podstatou odstrašující — tajemná technologie, kterou vládnou jen ti, jimž se v pop kultuře říká “hackeři” a “počítačoví mágové”. Ve skutečnosti to až tak šílené není. Je to sada směšně jednoduchých nástrojů, které si vytvořili v sedmdesátých letech minulého století zaměstnanci společnosti Bell (nyní AT&T) pro řešení většinou jednoduchých úloh. Vztahuje se ke “kosmickému věku“ asi tak jako vaše mikrovlnná trouba.

Tato sada je také nesmírně užitečná — asi jako když přejdete od stavby domu holýma rukama k mocným nástrojům těžké mechanizace. Prostřednictvím několika málo pojmů a metafor budeme moci osvítit i nejtemnější zákoutí příkazového řádku.

Jedním z nejdůležitějších těchto pojmů je cesta, neboli Path.

Některé front-endové frameworky, preprocesory CSS, JavaScriptové knihovny i jiné nástroje webového vývoje se spoléhají na to, že už máte na stroji něco nainstalované, obvykle buď Ruby, nebo Node.js. Jedním z takových nástrojů je Bower. Tyto nástroje vás neustále vedou k tomu, abyste byli v interakci s Path. Je tomu tak proto, že Path musí vědět o všech nástrojích, které instalujete pro své vývojové prostředí, nutná podmínka, aby mohl řádně fungovat váš příkazový řádek.

Snažit se porozumět, jak funguje Path, možná připadá jako zbytečný návrat do dob minulých, ale čím častěji používáte nástroje příkazového řádku, tím větší je šance, že Path způsobí nějaké potíže. Neztrácejte celé hodiny svého drahocenného času — a nezačněte na obrazovce vyhazovat objemné věci — raději si se mnou projděte základy práce s Path.

Skromná nenápadná proměnná

$PATH, jak vyjadřují uvozující prefix dolar a název v samých velkých písmenech, je na Unixu proměnná prostředí. V této proměnné je uložený seznam cest k adresářům, jednotlivé položky se oddělují dvojtečkou. Obsahuje tedy něco podobného jako je tohle:

/root/adresar/binary:/root/jiny_adresar/jiny_binary

Pokud patříte mezi puristy co do pojmenovávání proměnných, možná se divíte, proč se nejmenuje $PATHS, když obsahuje více cest. Soudím, že název je v jednotném čísle patrně proto, že má vyjádřit “načítací cestu složenou z více individuálních cest”. A tak to taky je.

Pokud jste zvědaví, jaké jiné druhy proměnných prostředí máte na svém systému, napište ve výzvě příkazového řádku příkaz env. Stiskněte Enter a uvidíte seznam všech momentálně existujících proměnných prostředí. (Pozn. překl. Na Windows se k proměnným prostředí dostanete tak, že kliknete pravým tlačítkem na Počítač, vyberete Vlastnosti, kliknete vlevo na odkaz Upřesnit nastavení systému, přejdete na záložku Upřesnit a kliknete na tlačítko Proměnné prostředí. Pak můžete pracovat se všemi uživatelskými i systémovými proměnnými prostředí. Pokud se chcete jen podívat, co je uloženo v  proměnné Path, stačí na příkazovém řádku napsat path. Windows nerozlišuje velikost písmen a dílčí cesty se oddělují středníkem.)

Protože $PATH je proměnná, můžete ji za pochodu podle svých přání modifikovat. Například, ve vašem shellu můžete napsat:

$ export PATH=prdlacky

Co to udělá? Nu, snažíme se spustit příkaz export uvedený výše v novém okně uvnitř vašeho terminálu nebo v té shellové aplikaci, kterou právě používáte, jako je Terminal na OS X.

Zkuste teď napsat jakýkoli základní příkaz Unixu, jako je třeba ls (list directory, výpis obsahu adresáře). Uvidíte -bash: ls: command not found, přestože by vše mělo jít jako na drátkách a ls by měl pracovat tak, jak je v kraji zvykem

Tato potměšilá sabotáž je prospěšná, protože nyní vidíme, že pokud nebudeme mít uvnitř $PATH patřičný obsah, neuvěřitelné se stane skutkem, poběží … prdlačky.

Ale proč? Protože podobně jak činí mnohé načítací cesty (včetně těch v programovacích jazycích a webových frameworcích jako je Rails), i tato proměnná Path určuje, co se může spustit ve vašem shellu. Pokud shell nenajde nic, co by souhlasilo s názvem, který jste napsali, nemůže to spustit.

A mimochodem, stačí opustit a restartovat vaši shellovou aplikaci, abyste obnovili všechny příkazy. Tohle byla jen dočasná sabotáž. Jen buďte obezřelí, abyste si nikdy tohle neuložili do svého ~/.bash_profile. To by pak bylo opravdu zlé.

Historka o příliš mnoha binárních souborech

Na Unixu se některým spustitelným programům říká binaries. Upřímně řečeno, je to dost nevhodně zvolený název, protože se soustřeďuje na jejich formát, nikoli na jejich funkci. Když pro řešení nějaké úlohy napíšete unixový program, je někdy třeba předem zkompilovat jeho zdrojový kód, teprve pak se může spustit. Tento kompilační proces vytvoří binární soubor (binary). Tyto soubory nepoužívají čistý text (jaký je v souborech zdrojového kódu), ale jistý binární formát, aby se jeho instrukce počítači snadněji zpracovávaly.

Unix přichází s mnoha adresáři, do nichž se binární soubory ukládají. Jaký je výchozí adresář pro jejich načítání, se dozvíte v souboru /etc/paths.

# obsah souboru vytiskne příkaz cat

$ cat /etc/paths

/usr/bin

/bin

/usr/sbin

/sbin

/usr/local/bin

Tento soubor obsahuje na každém řádku jeden adresář. Cesty jsou uvedené v pořadí, které má svůj význam. Když se na jedné z cest najde binární soubor, načte se. Pokud se binární soubor se stejným názvem najde ještě na jiné cestě, už se ignoruje. Tedy, cesty uvedené dřív mají přednost před cestami uvedenými později.

A to je právě důvod, proč se běžně vyskytují potíže, když se pokoušíte instalovat binární soubor něčeho, co už na systému máte. Pokud se jedná o OS X, tak jestliže se pokusíte nainstalovat jinou verzi Git než je ta, kterou jste dostali se systémem, ocitnete se právě v těchto potížích. To je velké zklamání vzhledem k tomu, že Git 2.0 je opravdu pěkný.

Pokud příkazem cd (change directory) změním adresář na /usr/bin — což je běžně používaný adresář, kam se ukládají binární soubory — a tam spustím ls, dostanu víc než tisíc výsledků. To mi moc nepomůže. Proto raději použiju ls v součinnosti s grepem (http://en.wikipedia.org/wiki/Grep). Pomocí ls | grep git vyfiltruji jen ty výsledky příkazu ls, které obsahují git.

$ ls | grep git

git

git-cvsserver

git-receive-pack

git-shell

git-upload-archive

git-upload-pack

Je dost jisté, že uvnitř /usr/bin bude nějaký binární soubor pro Git. Poctivá instalace OS X by měla vrátit /usr/bin/git, když vydáte příkaz which git (Pozn. překl. which je příkaz Unixu, jímž se zjišťuje umístění spustitelných programů. Volba -a (–all) vytiskne všechny vyhovující spustitelné programy v PATH, ne pouze první z nich.)

$ which git

/usr/local/bin/git

Proč je to ale u mne jinak? Lepší představu o tom, co se děje, dostaneme, když v příkazu which uvedeme volbu -a:

$ which -a git

/usr/bin/git

/usr/local/bin/git

Sděluje mi, že jsou na mém systému nainstalované dvě verze Git. Když ze svého příkazového řádku vydávám příkazy git, používá se pouze první z nich.

Úpravy cest

Já jsem nainstaloval svou vlastní verzi Git pomocí Homebrew, což je manažer balíků pro OS X. Mám totiž rád kontrolu nad nástroji, které používám každodenně, a které aktualizuji tehdy, když já usoudím, že je to vhodné. Mohl bych sice z OS X aktualizovat Git, který mi nainstaloval systém, nemám však ani potuchy o tom, jaké další binární soubory nebo aplikace mohou být na něm závislé.

Viděli jsme, že se binární soubory prohledávají v závislosti na pořadí, které je uložené v souboru s názvem /etc/paths, tak co kdybychom tam prostě pořadí dílčích cest změnili?

V souboru /etc/paths vidím, že složka /usr/local/bin, kde je uložena má verze Git, kterou nainstaloval Homebrew, je uvedena jako poslední. To znamená, že před ní má přednost binární soubor git uložený v /usr/bin, a moje úžasná nová verze Git se ignoruje. To ale vůbec není pěkné.

Mohli byste se sice pokusit modifikovat pořadí v /etc/paths, aby vyhovovalo vašim potřebám, umístit tedy /usr/local/bin úplně nahoru. Pak by se jako první načítala verze Git, kterou nainstaloval Homebrew. Navzdory tomu, že v diskusích StackOverflow mnohokrát narazíte na tuto radu, nedělejte to. Nikdy. Konfigurace uložené v /etc/ ovlivňují celý systém. Nejsou zde proto, aby je měnili jednotliví uživatelé (nemá se to dělat ani tehdy, pokud jste vy jediným uživatelem svého stroje), a pokud byste se v nich začali vrtat, mohli byste si snadno přivodit všelijaké nepředvídatelné potíže. Například, na původním pořadí v /etc/paths mohou být závislé některé utility, které používá OS X.

Udělejte to jinak. Měli byste upravit $PATH ve vašem prostředí, pomocí vašeho .bash_profile — toho, který je uložený v /Users/vaseuzivatelskejmeno/.bash_profile.

Nemusíte udělat nic víc, než zajistit, aby se nejdřív prohlížel /usr/local/bin. Proto do svého .bash_profile zařaďte toto:

# vnitřek profilu /Users/olivierlacan/.bash_profile

export PATH=/usr/local/bin:$PATH

Tím exportujete novou proměnnou prostředí $PATH, jež vznikne vypsáním dosavadní $PATH, ke které je jednoduše zleva k ostatním cestám přidána cesta /usr/local/bin. Poté, co svůj ~/.bash_profile uložíte a restartujete svůj shell, tak až si opíšete obsah $PATH příkazem echo, měli byste uvidět tohle:

$ echo $PATH

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Jak vidíte, je cesta /usr/local/bin uvedena v $PATH dvakrát, ale to nevadí. Protože je uvedena jako první, všechny binární soubory, které se načtou při první návštěvě této cesty, se už budou ignorovat, až se navštíví její druhý (poslední) výskyt. Já si upřímně přeju, aby existoval nějaký bezpečný a jednoduchý způsob, jak měnit pořadí cest, ale většina řešení, která znám, bývají složitější, než je zdrávo. Vždy je možné úplně překrýt výchozí $PATH, to ale předpokládá, že přesně víte, co děláte, a které cesty je třeba do ní zařadit.

Rozcestí v cestě

Když teď máte proměnnou prostředí $PATH takovou, jakou jste ji chtěli mít, zkontrolujte, zda se opravdu zavolá patřičný binární soubor, když vydáte příkaz git:

$ which git

/usr/local/bin/git

 

$ git –version

git version 2.0.0

/usr/bin/git –version git version 1.8.5.2 (Apple Git-48)

Máte to. Git 2.0.0 (verze, kterou nainstaloval Homebrew) je nyní tou, která reaguje na příkazy git, a verze 1.8.5.2, kterou nainstaloval Apple, byla upozaděna. Pokud byste náhodou už nadále nechtěli používat verzi git 2.0.0, prostě byste ji odinstalovali a její pozici by opět hladce převzala výchozí verze.

Chraňte svou cestu

Spousta utilit pro vývojáře (a designéry) automaticky při instalaci vstřikuje kód do .bash_profile. Často se vám o tom ani nezmíní, takže pokud ve svém profilu najdete vypsané nějaké podivné cesty, možná to vysvětluje, proč načtení nové relace (k čemuž dochází, když otevřete okno či záložku nějakého nového shellu) trvá déle, než by mělo: přecpané $PATH může chvíli trvat, než se načte.

Takhle momentálně vypadá moje cesta:

/Users/olivierlacan/.rbenv/shims:/Users/olivierlacan/.rbenv/bin:/usr/local/bin:/usr/local/heroku/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/MacGPG2/bin

Vypsaná v tomto tvaru se špatně čte, proto ji raději vypisuji po řádcích, na každém řádku jedna cesta. To se snadno zařídí příkazem tr (translate characters):

$ echo $PATH | tr ‚:‘ ‚\n‘

/Users/olivierlacan/.rbenv/shims

/Users/olivierlacan/.rbenv/bin

/usr/local/bin

/usr/local/heroku/bin

/usr/bin

/bin

/usr/sbin

/sbin

/usr/local/bin

/opt/X11/bin

/usr/local/MacGPG2/bin

V $PATH je uloženo hodně informací a ve svislém uspořádání jsou mnohem srozumitelnější. Vyzkoušejte si to na svém stroji, a pokud zjistíte, že nevíte, kde se ve vaší $PATH vzal některý z vypsaných řádků, dejte si za úkol to zjistit. Třeba se něco užitečného naučíte.

Vědět o tom, že existuje nějaká $PATH, a k čemu slouží, možná nepřipadá jako znalost, která by mohla být k něčemu dobrá. Ale i na pozici webového umělce budete patrně muset někdy při své práci komunikovat s nástroji příkazového řádku — a jednoho krásného dne se může stát, že některý z těchto nástrojů nepoběží nebo poběží jinak, než čekáte. Když ale budete vědět, co je vaše cesta Path, jak by měla vypadat, pokud je čistá a jasná, jak se má řádně modifikovat, a jak se zkontroluje, zda bere v úvahu vaše nástroje, je dost velká šance, že vám bude trvat jen několik minut, ne hodin, než se budete moci zase vrátit na svou skutečnou tvůrčí cestu: na které budujete věci pro lidi.

O autorovi

Olivier Lacan

Olivier Lacan je softwarový vývojář u Code School. Jako webového designéra ho neuspokojovalo stavět jen polovinu lodi, takže se stal závislým na programování v jazyku Ruby. V současné době píše články zaměřené na nejrůznější témata a snaží se, aby byl svět open source softwaru trochu vlídnější.

Článek byl přeložen se souhlasem Alistapart.com

Původní článek: The $PATH to Enlightenment

  • Translation: RNDr. Jan Pokorný
  • Language and expert collaboration: Marek Machač
Štítky: git

Mohlo by vás také zajímat

Nejnovější

2 komentářů

  1. Mirek

    Dub 13, 2015 v 12:55

    Překlad není špatný, přesto je místy trochu divný.

    „Tím exportujete novou proměnnou prostředí $PATH, kterou tvoří na začátku, vlevo od všech dalších cest, vaše cesta /usr/local/bin, za ní pak následuje existující $PATH.“

    Tuhle větu jsem si musel přečíst v originále, abych ji pochopil. Přeložil bych ji spíš takto:

    „Tím exportujete novou proměnnou prostředí $PATH, jež vznikne vypsáním dosavadní $PATH, ke které je jednoduše zleva k ostatním cestám přidána cesta /usr/local/bin.

    dále:

    „Možná jste se právě dozvěděli něco užitečného.“ – přeložil bych: „Třeba se něco užitečného naučíte.“

    „poběží nijak, než čekáte“ (překlep)

    „co je vaše cesta Path“ – poslední odstavec je pokus autora článku o paralelu mezi $PATH jako cestě k souborům a cestě, kterou kráčíme životem. To snad ani nelze přeložit, když už, tak třeba „webový umělec“ působí klopotně,“web craftperson“ je asi „webař“, nebo tak něco.

    Jsem rád za tyto články, překládejte dál ;-)

    Odpovědět
    • Marek Machač

      Dub 13, 2015 v 13:27

      Děkuji za doplnění a návrh úprav. Většinu Vašich vět jsem s dovolením po znovupřečtení překladu využil.

      Jsem rád,že se vám jinak překlady líbí a určitě budeme dále pokračovat.

      Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *