Hlavní navigace

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

25. 3. 2008
Doba čtení: 5 minut

Sdílet

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:

root_podpora

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.

Byl pro vás článek přínosný?