Fórum Root.cz
Hlavní témata => Software => Téma založeno: TC 18. 04. 2015, 10:34:09
-
Mějme adresárovou strukturu:
rel
/01
/02
/03
shared/config
cur -> rel/01
Adresářový strom rel s verzemi, potom odkaz cur na jednu z verzí a potom sdílený adresář shared/config.
Sekvence příkazů:
cd cur
cd ../shared/config/
ls -la
Projde bez chyby. Sice nefunguje doplňování přes tab u toho příkazu cd (což je podezřelé), ale projde to.
Jenže:
cd cur
ls -la ../shared/config/
ls: cannot access ../shared/config/: No such file or directory
Skončí chybou.
Není to jen výpis adresáře, pokud jsem v adresáři cur tak i výpis souboru cat ../shared/config/config.file skončí chybou.
Může toto chování někdo vysvětlit? Je to chyba nebo vlastnost?
-
Musis ist este o uroven vyssie
ls -la ../../shared/config
-
Zkus si pwd overit, kde skutecne jsi.
-
Ano, o úroveň výš to funguje, ale má se to tak chovat?
Pokud bude adresář cur skutečný adresář do kterého nakopíruji obsah verze, tak už to nebude ../../shared/ ale jen ../shared/. Přece se logická cesta nemůže lišit je podle toho, zda je to link nebo fyzický adresář.
Pwd jsem zkoušel, potom mě napadlo ověřit si čísla inodů:
takže kořen tohoto našeho stromu je 579526
rel/ je 579549
rel/01 je 579551
cur je 579551-- to je správně
jenže když jsem v cur, tak stat ../ je 579549 (což je adresář rel a nikoliv náš kořen). Zatímco cd ../ a stat . správně napíše inode 579526
-
Vidím spíš chybu v chování sekvence
cd cur
cd ../shared/config/
ls -la
která by podle mne měla selhat, protože po provedení cd cur se nacházíš v adresáři rel/01.
-
Zkus si pwd overit, kde skutecne jsi.
Pokud používáte bash tak pozor, tam se pwd ve vztahu k symlinkům chová jinak než by spousta lidí očekávala.
-
Co se týče zjištění skutečného aktuálního adresáře, může být pohodlnější použít program /bin/pwd namísto statu a zjišťování čísel uzlů.
Proč symbolické odkazy fungují právě takto, se nejlépe ukáže na následujících příkazech:
$ cd rel/02
$ ln -s ../01 prev; ln -s ../03 next
Aby odkazy na předchozí a následující adresář fungovaly správně všude, tj. i při vstupu do symbolicky linkovaného adresáře <code>cur</code>, musejí být vyhodnoceny vzhledem k adresáři, v němž jsou vytvořeny.
-
Co se týče zjištění skutečného aktuálního adresáře, může být pohodlnější použít program /bin/pwd namísto statu a zjišťování čísel uzlů.
stat jsem použil právě proto, protože se pwd chovalo v rozporu s manem. Ano, problém byl v tom, že se volal pwd z bashe, ale man ukazoval manuál z balíčku coreutils.
$ pwd
/home/test/cur/prev
$ /bin/pwd
/home/test/rel/01
což je fakt super a tak jsem se krásně střelil do nohy. Budu to muset v klidu projít ještě jedou, protože mám podezření, že bash po nějakém nedávném update ukazuje a vyhodnocuje linky jinak.
Dobře tedy, pokud se to má chovat takto (zvláštní, že jsem na to za posledních 10 let nenarazil a pokaždé se to chovalo "intuitivně" správně), tak v tom případě je fakt rozbité to cd. Nebo možná není rozbité, exisituje nějaká proměnná prostředí, který ovlivňuje chování "rozbalování" symlinků? Protože bash se v některých případech tváří, jako kdyby symlikové adresáře byly totéž co fyzické.
-
Ono zalezi, jak na to clovek pohlizi. U cd mi prijde logictejsi, ze "cd .." vraci tou cestou, kterou jsem prisel, tj pres symlinky. Kdyby to bylo jinak, docela blbe by se s tim pracovalo...
Spis je problem v ls, kdy "ls ../adresar" se nejdriv odkaze o uroven vys ve fyzicke adresarove strukture, misto te symlinkove cesty, a tam potom hleda ten adresar. Zadny prepinac, ktery by to zmenil, jsem nenasel :o
-
Tady jsou dva odkazy týkající se tohoto problému:
http://unix.stackexchange.com/questions/36319/symbolic-link-to-a-directory-and-relative-path
http://stackoverflow.com/questions/7665/how-to-resolve-symbolic-links-in-a-shell-script
Kromě /bin/pwd jsou pro získání skutečné cesty ještě možnosti: pwd -P
případně readlink -f .
nebo readlink -f $PWD
Jak zapsat relativní cestu, která by respektovala symlinky (o což zde asi jde především) ovšem nevím, nejspíš to ani nejde.
Příkaz ls -la ../shared/config/
by sice šel nahradit cd ..; ls -la shared/config; cd -
případně pushd .; cd ..; ls -la shared/config; popd
praktické mi ovšem nepřijde ani jedno.
-
Ono zalezi, jak na to clovek pohlizi. U cd mi prijde logictejsi, ze "cd .." vraci tou cestou, kterou jsem prisel, tj pres symlinky. Kdyby to bylo jinak, docela blbe by se s tim pracovalo...
Našel jsem tuto diskusi, kde někdo řeší v podstatě totéž.
https://www.linuxquestions.org/questions/linux-newbie-8/symbolic-links-to-directories-mystery-898683/
Spis je problem v ls, kdy "ls ../adresar" se nejdriv odkaze o uroven vys ve fyzicke adresarove strukture, misto te symlinkove cesty, a tam potom hleda ten adresar. Zadny prepinac, ktery by to zmenil, jsem nenasel :o
Je to přesně tak no. Bash pracuje ve "své" logické struktuře, zatímco programy z něj volané pracují ve fyzické struktuře.
Mělo by to jít nastavit přes set -P.
-P If set, the shell does not resolve symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the logical chain of directories when performing commands which change the current directory.
-
Vlastně tady je řešení (hack): http://unix.stackexchange.com/a/43645/83224
místo
ls -la ../shared/config/
psát
ls $(dirname $PWD)/shared/config
nic příliš pěkného, ale lze to použít přímo v cestě
-
resp.
ls -la $(dirname $PWD)/shared/config
-
Pokud vim, ten link muze byt relativni a absolutni, pokud je relativni, musi se s tim pocitat, protoze odkazuje vzdy relativne k adresari, ze kteryho prijde dotaz. Pokud je absolutni, tak to bude fungovat OK, ale muze to byt neprijemny, kdyz se to nekam presune nebo se pouzivat chroot a pod.
Takze pokud bude ta struktura hypoteticky v /home/rel/...
a ten link misto na rel/01 pude na /home/rel/01 .... melo by to fungovat zcela bez ohledu na to, odkud se to zavola.