Я создал символическую ссылку с абсолютным путем к каталогу (Blink) и, например, следующее дерево:
$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr 3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr 3 12:27 foo
$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr 3 12:27 bar
затем я иду в / tmp / A и меняю каталог на Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
возвращает меня, /tmp/A
но если я наберу, например, ls ../foo
я получу ошибку:
ls: ../foo: No such file or directory
встроенная команда cd разрешает путь по мере необходимости, но внешние ls рассматривают .. как верхний уровень / tmp / B и поэтому не могут найти foo.
В чем здесь проблема? Могу ли я получить файл foo из / tmp / A / Blink по относительному пути, например ../foo?
Ответы:
Я не думаю, что вы можете сделать это. Оболочки в настоящее время отслеживают, как они оказались там, где они находятся, они отслеживают текущий рабочий каталог по имени, а не просто полагаются на файловую систему и ОС для ее сохранения. Это означает, что встроенная функция
cd
может выполнять «резервное копирование» символической ссылки, а не просто следовать цепочке «..» напрямую.Но когда вы запускаете
ls ../foo
,ls
вы не знаете, что оболочка попала в каталог по символическим ссылкам.ls
будет делатьstat()
на "../foo". Часть ".." происходит из текущего каталога, который имеет только одну запись ".." для своего родителя. Вся эта символьная ссылка не меняет способ, которым каталоги имеют один "." и единственная запись "..". Символические ссылки позволяют ядру вставлять дополнительный слой косвенности в пути к файлам. Когда вы передаете «../whwhat» вopen()
илиstat()
, ядро просто использует текущий рабочий каталог процесса, выполняющего вызов, чтобы выяснить, какой единственный каталог назван «..».источник
Оболочка хранит текущий рабочий каталог в
$PWD
. Это то , что используется для встроенных команд оболочкиcd
иpwd
, и он рассматривает символические ссылки , как обычные каталоги, как вы уже видели. Иногда это полезно, иногда нет.Вы можете найти реальный каталог, используя
pwd
(введитеhelp pwd
для более подробной информации):Кроме того,
cd
есть вариант-P
(опять же,help cd
ваш друг):Наконец, вы можете полностью отключить «функцию»:
источник
set -P
и ls начинает иметь смысл. :)Брюс и Амс дали прекрасные ответы, объясняющие поведение позади. Но чтобы на самом деле сделать то, что
ls ../foo
вы просили, вы могли бы пойти с чем-то вродеисточник
Вы не можете сделать это, потому что
/tmp/A/Blink
на самом деле/tmp/B
. Итак,ls ../A/foo
работает.Вместо этого , вы можете найти его полезным , чтобы иметь возможность кд в реальный
/tmp/B
каталог, а не псевдонимы/tmp/A/Blink
. Чтобы сделать это, вы можете использовать следующую функцию вместоcd
(которую вы можете поместить в ваш .bashrc)lcd
Конечно, работает для нормальных и символьных каталогов.Примечание:
readlink -f
действует на конечную цель ссылки (когда ссылки связаны последовательно).источник
cd -P
кажется проще.