Hrátky z řádky: Kouzla s adresáři

Ondřej Bojar 25. 3. 2008

Opět se setkáváme u pravidelné pondělní dávky tipů a triků z černé řádky. V dnešním článku nás po malinko nudném úvodu čeká sbírka užitečných triků pro práci s adresáři. Naučíme se rychle přepínat adresáře v bashi, manipulovat s cestami, používat aliasy a schránku na adresáře a podíváme se i na ssh.

Základní pravidla systému souborů

Adresář je v unixových filesystémech jen speciální druh souboru. Jeho obsahem je prostě seznam vnořených položek (souborů, adresářů…) Zdání hierarchické struktury je docíleno těmito pravidly:

  • Existuje právě jeden kořenový adresář a označuje se „/“.
  • Každý adresář s výjimkou kořenového obsahuje povinně položku „..“, což je hard link (zástupce, odkaz neodlišitelný od originálu, viz níže) na „nadřazený“ adresář. (Navíc každý adresář obsahuje hardlink sám na sebe pod názvem „.“.)
  • Žádné další hardlinky na adresáře nejsou dovoleny. (Struktura by jinak mohla začít obsahovat cykly.)

Díky hierarchické struktuře ke každému souboru existuje právě jedna „kanonická“ absolutní cesta začínající lomítkem a přes řadu adresářů vedoucí k souboru.

Domovský adresář

Každému uživateli je přidělen jeden „domovský“ adresář. Pro pohodlí je možné k domovskému adresáři užívat cestu ~ (tidla), resp. ~username, chcete-li domovský adresář jiného uživatele. Plná cesta je však typicky /home/username a někdy je uložena v proměnné prostředí  $HOME.

Aktuální adresář

Každý proces má „aktuální adresář“, tj. adresář, od něhož se vyhodnocují relativní cesty (cesty nezačínající lomítkem ani tildou). Aktuální adresář někdy lidé označují tečkou (např. „ ./soubor“), což je pravda díky tomu, že aktuální adresář obsahuje tečku jako hardlink na sebe.

Proces může požádat o změnu aktuálního adresáře a v bashi k tomu samozřejmě slouží příkaz  cd.

Zkratky cest a podstrčení vlastního vstupu

Unix dovoluje vytvářet zástupce souborů či adresářů dvou typů: hardlinky a symlinky, obojí příkazem ln (přidejte parametr -s pro symlink). V obou případech se uživateli zdá, že ke stejnému obsahu se dostal dvěma různými cestami. V případě hardlinku však nelze říct, co je originál a co odkaz (dokonce i přístupová práva a čas změny se sdílí). Ať smažete kterýkoli, pod druhým jménem data najdete. Obsah souboru končí v nenávratnu až mazáním všech jeho „jmen“. Symlink je analogií zástupců z jiných operačních systémů. Jde o nezávislý soubor, obsahující buď absolutní nebo relativní cestu k cíli. Smazáním originálu jsou data v tahu a zbude neplatný symlink.

Symlinky lze užít pro vyrábění zkratek v cestách. Takto např. získáte ve svém home odkaz na adresář namountovaného cdčka:

cd ~; ln -s /media/cdrom ./cd

Čili odteď můžete k souborům na CD přistupovat takto (první cd bez parametru vás přesune do domovského adresáře):

cd; cd cd

Symlinky se též hodí, chcete-li podstrčit programům vlastní adresář. Takto (máte-li rootovská práva) můžete /tmp přestěhovat na větší disk:

su
cd /; mv tmp tmp-old
mkdir /big-disc/tmp
chmod ugo+rwxt /big-disc/tmp # vhodná práva pro temp
ln -s /big-disc/tmp /

Rychlé přepínání adresářů v bashi

Do „minulého“ adresáře se můžete přepnout následujícími příkazy:

cd -
# nebo
cd $OLDPWD

Pokud vám jeden krok zpět nestačí, užívejte místo cd příkaz pushd a vracejte se příkazem popd:

pushd /media/cdrom
pushd ~/adresář
popd # a jsme zpátky na CD

Tak jako proměnná $PATH obsahuje seznam adresářů, kde bash hledá programy, $CDPATH obsahuje seznam adresářů, odkud lze provést cd, aniž byste tam napřed chodili:

export CDPATH=.:/media
# a nyní můžete kdykoli zadat:
cd cdrom
# nebo
cd usbdisk

Jaký význam má asi ta „ .:“ na začátku $CDPATH?

Jak vypsat aktuální adresář a další užitečné manipulace s cestami

Cestu k aktuálnímu adresáři můžete nechat vypsat příkazem:

pwd

Základní manipulaci s cestou umožňují příkazy dirname a basename:

dirname /cesta/k/souboru
# vypíše: /cesta/k
basename /cesta/k/souboru
# vypíše: souboru

Takže např. prosté jméno aktuálního adresáře dostanete takto:

basename `pwd`

Velmi užitečná varianta chybí, tak ji doprogramujme. Často se totiž hodí z okna terminálu dostat plnou cestu k souboru (a pak ji vložit např. do okna „Attach file“ vašeho klikacího e-mailovače).

echo 'echo $1 | sed "s:^\([^/~]\):""`pwd`""/\1:"' > pathname
chmod +x pathname

Náš nový skript vypíše celou cestu k udanému souboru, např. byli-li jsme v adresáři /home/ja/pokusy:

./pathname odsud/dal
# vypíše /home/ja/pokusy/odsud/dal

Uvedený regulární výraz sedu dělá to, že první písmeno (není-li to /, ani ~) na řádce chytí do závorek \( a ) a nahradí aktuálním adresářem (a obsahem prvních závorek, \1, tj. tím smazaným písmenem). K tomu trochu uvozovkové bashové magie. S nápovědou, že jako $1 zastupuje první argument skriptu, zastupuje "$@" celou řádku argumentů, a odkazem na for-cyklus jistě dokážete skript vylepšit, aby uměl zpracovat víc než jeden argument.

Aliasy a „schránka“ na adresáře

„Alias“ je zkratka za příkaz. Zásadní rozdíl mezi aliasem a malým skriptem spočívá v tom, že alias interpretuje aktuální bash, nikoli podproces. Když tedy např. provedete cd v aliasu, adresář bude změněn i po „skončení“ toho aliasu. Když provedete cd ve skriptu, proces vašeho bashe se o změně adresáře nedozví.

Po tomhle tipu doufám pochopíte, že i bez Midnight Commanderu, mc, (nebo tím spíš) může být pohyb v adresářové struktuře velmi rychlý. Vyrobením dvou aliasů získáte možnost aktuální adresář „uložit do schránky“ ( mcd) a v libovolném jiném terminálu jej „vyvolat“ ( rcd), tj. přejít do něj:

alias mcd='pwd > ~/.dirclip'
alias rcd='cd $(cat ~/.dirclip); pwd'

Povšimněte si, že rcd nejen do adresáře přejde, ale taky jej vypíše. Kromě připomenutí, kam jsme se teleportovali, to výborně poslouží např. při kopírování:

# v jednom okně
cd dlouha/slozita/cesta
mcd
# v jiném okně
cd jina/dlouha/cesta
cp soubor `rcd`
# soubor se zkopíroval do "adresáře prvního okna"

Já mám takovýchle schránek jedenáct: rcd/ mcd, rcd0/ mcd0, …, rcd9/ mcd9. A navíc příkaz cds, který mi jejich obsahy připomene. Rychle se tak přepínám mezi projekty, na nichž pracuji. Navíc mne schránky ušetří otravného klikání v okénkách „Save file/attachment as…“. Soubor vždy uložím do home a pro „zatřídění“ užiju mnohem rychlejší:

mv ~/zacatek_jmena_soubomu<TAB> `rcdX`

Pro založení číslovaných schránek přidejte do svého ~/.bashrc toto:

for i in "" `seq 0 9`; do
  alias mcd$i="pwd > ~/.dirclip$i"
  alias rcd$i='cd $(cat ~/.dirclip'"$i"'); pwd'
done
alias cds='for i in " " `seq 0 9`; do if [ -e ~/.dirclip$i ]; then echo -n "$i "; cat ~/.dirclip$i | sed "s:^$HOME:~:"; else echo ""; fi; done'

ssh se zachováním adresáře

V prostředí s více počítači a sdíleným systémem souborů se často hodí ssh se zachováním aktuálního adresáře. Jednoduchý trik spočívá v tom, že si napřed uložím aktuální cestu do pomocného souboru ve sdíleném adresáři (jako příklad uvádím ~/.autochdir, čili předpokládám, že i home máte sdílený přes všechny počítače), provedu ssh, a v .bashrc  aktivně hledám ten pomocný soubor. Pokud jej najdu, přepnu se do daného adresáře a soubor smažu. (Trik samozřejmě havaruje, pokud současně budete otevírat dvě ssh spojení.) Do svého ~/.bashrc přidejte následující řádky:

alias sshcwd="pwd > ~/.autochdir; ssh"
# Pokud existuje ~/.autochdir, přesuňme se tam, kam říká:
[ -e ~/.autochdir ] && cd `cat ~/.autochdir`
# A v každém případě ~/.autochdir tiše zkusme smazat:
rm -f ~/.autochdir

Nyní bude stačit napsat:

cd /nejaka/slozita/cesta/ve/sdilenem/prostoru
sshcwd druhy_stroj

A i na druhém počítači se rázem octnete v tomtéž adresáři.

Našli jste v článku chybu?
Měšec.cz: Cestujte bez starostí, získejte výhodné pojištění

Cestujte bez starostí, získejte výhodné pojištění

Podnikatel.cz: Zůstat na Heurece je čiré bláznovství

Zůstat na Heurece je čiré bláznovství

Podnikatel.cz: Babiš představil daňovou revoluci Moje daně

Babiš představil daňovou revoluci Moje daně

DigiZone.cz: ČRa hodnotí pilotní 4K vysílání

ČRa hodnotí pilotní 4K vysílání

DigiZone.cz: Nova stahuje bonus díl „Tvoje tvář má...“

Nova stahuje bonus díl „Tvoje tvář má...“

Vitalia.cz: Margit Slimáková nesnáší rajskou, Petr Fořt pizzu

Margit Slimáková nesnáší rajskou, Petr Fořt pizzu

Vitalia.cz: 5 porcí ovoce a zeleniny: no ale jak na to?

5 porcí ovoce a zeleniny: no ale jak na to?

DigiZone.cz: Robinsonův ostrov moderuje Novotný

Robinsonův ostrov moderuje Novotný

Lupa.cz: Vzali věc, která fungovala, a přidali internet

Vzali věc, která fungovala, a přidali internet

DigiZone.cz: ČTÚ květen: rušení TV vysílání narůstá

ČTÚ květen: rušení TV vysílání narůstá

DigiZone.cz: Mobilní aplikace pro DVTV je tady

Mobilní aplikace pro DVTV je tady

Lupa.cz: Text umírá, na webu zbude jen video

Text umírá, na webu zbude jen video

DigiZone.cz: Satelitní Flix TV vyráží do boje

Satelitní Flix TV vyráží do boje

Podnikatel.cz: 10 citátů Billa Gatese: tesat do kamene

10 citátů Billa Gatese: tesat do kamene

Měšec.cz: Ceny PHM v Evropě. Finty na úspory

Ceny PHM v Evropě. Finty na úspory

Lupa.cz: Nej aplikace? Vodafone, Mozkovna, Záchranka

Nej aplikace? Vodafone, Mozkovna, Záchranka

DigiZone.cz: Pardubicko: Výrazně posílen Mux 3

Pardubicko: Výrazně posílen Mux 3

DigiZone.cz: Slováci první, Češi třetí. Krásný...

Slováci první, Češi třetí. Krásný...

Vitalia.cz: Máte chutě? Nejezděte do světa, ale do Dobřichovic

Máte chutě? Nejezděte do světa, ale do Dobřichovic

Podnikatel.cz: Výpadek internetu a #EET. Co s tím?

Výpadek internetu a #EET. Co s tím?