Как определить, действительно ли я нахожусь в расположении символической ссылки из командной строки?

33

Предположим, у меня есть папка:

cd /home/cpm135/public_html

и сделать символическую ссылку

ln -s /var/lib/class .

Позже я в этом каталоге:

cd /home/cpm135/public_html/class

pwdСобирается сказать мне , что я нахожусь в/home/cpm135/public_html/class

Есть ли способ узнать, что я "действительно" в /var/lib/class? Благодарность

Оливер Уильямс
источник
1
Некоторые оболочки не позволяют вам находиться внутри символической ссылки. Например, fishоболочка автоматически разрешает символическую ссылку, когда вы cdв нее входите .
trysis

Ответы:

56

В зависимости от того, как pwdнастроена ваша команда, она может по умолчанию показывать логический рабочий каталог (вывод с помощью pwd -L), который будет показывать местоположение символической ссылки, или физический рабочий каталог (вывод с помощью pwd -P), который игнорирует символическую ссылку и показывает «настоящий» каталог.

Для полной информации вы можете сделать

file "$(pwd -L)"

Внутри символьной ссылки это вернет

/path/of/symlink: symbolic link to /path/of/real/directory
Занна
источник
1
да, -Pфлаг был тем, что мне было нужно. Спасибо
Оливер Уильямс
6
Для того, чтобы также ответить на вопрос в названии, просто использовать test "$(pwd -L)" = "$(pwd -P)" && echo No symlinks(или заменить && echo No symlinksс || echo Symlinks).
CVN
1
Это отвечает на вопрос совершенно без необходимости повторять. Если бы вопрос был «Как отобразить сообщение, если я нахожусь в каталоге с символическими ссылками?», Тогда потребуется эхо.
Arronical
file "$(pwd)"работает только если символическая ссылка является последним компонентом каталога. Он не обнаруживает символическую ссылку OP, когда CDed к /home/cpm135/public_html/class/foo/bar. Я ничего не знаю о том, что печатает информацию для всех символических ссылок в путевом имени, но вы также можете использовать realpath ., что, я думаю, эквивалентноpwd -P
Peter Cordes
17

Обратите внимание, что pwdна самом деле это встроенная оболочка. В зависимости от вашей оболочки и ее конфигурации результаты могут меняться. Для более портативного решения, вы должны использовать /bin/pwd. Фрагмент страницы руководства:

NAME
       pwd - print name of current/working directory

SYNOPSIS
       pwd [OPTION]...

DESCRIPTION
       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

       --version
              output version information and exit

       If no option is specified, -P is assumed.

       NOTE:  your  shell  may  have  its  own  version of pwd, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

В общем, вы можете разрешить полный канонический путь любого файла / каталога, используя readlink -f. readlink -f .работает аналогично pwd -P.

Gowtham
источник
2
Несмотря на то, что я узнал трудный путь , который readlink -fне доступен на всех юниксы (например , не доступны на OS-X)
abligh
3

Вы действительно /home/cpm135/public_html/class- это единственный правильный ответ на вопрос «каков мой текущий рабочий каталог».

Когда вы ссылаетесь на /var/lib/class... это не совсем о том, где вы находитесь, а больше о том, каким путем вы туда добирались .

Когда вы запускаете /bin/pwd, он выясняет ваш текущий рабочий каталог, посмотрев на. и .. каталоги (перечисленные вверху ls -la), определяющие , какой каталог в .. совпадает с. и затем работает в обратном направлении до .. и. обратитесь к той же директории. Как только все это будет сделано, он знает, какой у вас текущий рабочий каталог.

Когда вы запускаете pwdвстроенную оболочку, она не следует этой процедуре (хотя при необходимости она может выполнить некоторые из них) - вместо этого она запоминает путь, который вы выбрали, чтобы попасть сюда. Поэтому каждый раз, когда вы выполняете cdкоманду, ваша оболочка запоминает это как часть пути, чтобы добраться до того места, где вы сейчас находитесь, и pwdвыводит на экран то, что она рассчитала на основе всех cdкоманд, которые вы выполнили - что может или не может быть вашим фактическим рабочий каталог.

Когда вы делаете a ln -s . fooи продолжаете работать cdв foo, все может стать очень странным - /bin/pwdскажет, что вы все еще находитесь в том же каталоге, но встроенная оболочка pwdскажет, что вы находитесь в нем, /foo/foo/foo/foo/foo/fooдаже если такого каталога вообще не существует. (Тем не менее, вы, вероятно, можете cd в это.)

Еще один источник путаницы - переименование каталогов. /bin/pwdзатем сразу же перейдет к изменению, но встроенный pwdне будет, пока вы не сделаете что-то, что скажет, что старое имя каталога не имеет значения.

dougmc
источник
1
Вы не отвечаете на вопрос, вы отклоняете его.
Дмитрий Григорьев
4
Хотя это не дает прямого ответа на вопрос , я думаю, что это полезный пост для понимания различия между pwdвстроенной оболочкой и /bin/pwdобъяснения того, как автономная версия предоставляет более полезную информацию (которая может ответить на исходный вопрос).
Энтони Дж - правосудие для Моники
1
Эти различия сводятся к вариантам -Pи -L, упомянутым в других ответах. Короче говоря, в некоторых реализациях по умолчанию используется одна, в другой - другая. В системе Centos, которую я должен передать, встроенная функция bash по умолчанию является логической, а /bin/pwdпо умолчанию - физической, но обе они принимают обе опции командной строки и согласовывают результат, когда они предоставляются.
IMSoP
1
Вопрос основан на неверной предпосылке - «есть ли способ узнать, что я« действительно »в / var / lib / class?» Тем не менее ... объясняя, что это на самом деле означает, это помогает ему понять, что он действительно ищет. Опции pwd -P и -L уже упоминались ...
dougmc
1
У вас есть аргумент в обратном направлении. ls ..покажет содержимое /var/lib, а не /home/cpm135/public_html. cd ..является особенным: оболочка выполняет специальное отслеживание «как вы туда попали» и фактически не выполняет chdir("..")системный вызов. Что касается ядра, текущий рабочий каталог вашей оболочки ( /proc/self/cwd) - это просто точка монтирования: пара узлов. Это похоже на дескриптор открытого файла в каталоге, поэтому переименование каталога не сломает вашу оболочку. ( cd .обновить $PWDпеременную оболочки ). Вы делаете полезное замечание, поэтому я бы высказался об этом, когда исправлюсь
Питер Кордес
1

По сути, вы спрашиваете, нужно ли показывать фактический путь к текущему рабочему каталогу. Ну есть с питоном и os.getcwd()функцией

Ниже вы видите небольшой тест из каталога «VirtualBox VMs», расположенного в моем домашнем каталоге. В действительности это символическая ссылка на другой каталог, расположенный на другом жестком диске, смонтированный в /mnt/HDD.

bash-4.3$ file "$(pwd)"
/home/xieerqi/VirtualBox VMs: symbolic link to /mnt/HDD/VirtualBox VMs/
bash-4.3$ python -c 'import os; print os.getcwd()'
/mnt/HDD/VirtualBox VMs

Как видите, Python os.getcwd()разрешает реальный путь к каталогу, а не путь символической ссылки.

Сергей Колодяжный
источник