`-L'
`--logical'
If the contents of the environment variable `PWD' provide an
absolute name of the current directory with no `.' or `..'
components, but possibly with symbolic links, then output those
contents. Otherwise, fall back to default `-P' handling.`-P'
`--physical'
Print a fully resolved name for the current directory. That is,
all components of the printed name will be actual directory
names--none will be symbolic links.
Встроенный pwdвключает символическую ссылку по умолчанию, за исключением того, что -Pиспользуется опция или -o physicalвстроенная установка set включена.
pwd [-LP]Print the absolute pathname of the current working directory.The pathname printed contains no symbolic links if the -P option
is supplied or the -o physical option to the set builtin command
is enabled.If the -L option is used, the pathname printed may
contain symbolic links.Thereturn status is 0 unless an error
occurs while reading the name of the current directory or an
invalid option is supplied.
/bin/pwdпо умолчанию игнорирует символическую ссылку, прочитайте часть info pwdв моем ответе: Напечатайте полностью разрешенное имя для текущего каталога. То есть все компоненты напечатанного имени будут фактическими именами каталогов - ни один не будет символической
cuonglm
@ user3581976: см. мой обновленный для более ясного.
cuonglm
Почему есть команда -L для pwd, хотя она установлена по умолчанию? И разве оболочка не использует команду / bin / pwd для запуска pwd?
user3581976
2
@ user3581976: Изображение, с которого вы запускаете оболочку set -o physical, теперь по умолчанию pwdявляется -Pопцией использования , если у вас нет -Lопции, как вы печатаете путь, содержащий символьную ссылку? Прочитайте это, https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlчтобы узнать, что set -o physicalделает.
cuonglm
7
Для процесса возможно опросить файловую систему, чтобы определить ее текущий рабочий каталог, используя метод, который является слишком сложным, чтобы быть в теме в качестве ответа на этот вопрос. Это то, что делают pwdпрограмма и getcwdфункция библиотеки. На заре Unix они были единственными способами узнать, каков ваш рабочий каталог. Вот часть ответа на ваш вопрос, которую я не могу найти ни в одном из других ответов или даже где-либо еще на этом сайте (после 42-секундного поиска):
Когда оболочка запускается, она получает свой текущий рабочий каталог (возможно, путем вызова getcwd).
После этого, всякий раз , когда вы делаете cd, pushdили popd, оболочка отслеживает рабочий каталог с помощью функции манипулирования строк. Например,
Если ваш рабочий каталог /home/simи вы печатаете cd .., оболочка вычисляет, что ваш рабочий каталог /home.
Если ваш рабочий каталог /home/simи вы печатаете cd ., оболочка вычисляет, что ваш рабочий каталог все еще /home/sim.
Если ваш рабочий каталог /home/simи вы печатаете cd aa, оболочка вычисляет, что ваш рабочий каталог /home/sim/aa- без проверки, aaявляется ли символическая ссылка.
Это позволяет сэкономить на стоимости звонков getcwd. Но это компромисс, поскольку он может привести к неверной информации.
Команда pwd(встроенная) просто отображает запомненное / вычисленное представление оболочки о том, что является рабочим каталогом.
Кроме того, оболочка помещает запомненное / вычисленное представление о том, какой рабочий каталог находится в переменной среды PWD, для удобства пользовательских процессов. Процесс никогда не должен полагаться на это, если ему нужна точная информация.
Итак, суть в том, что оболочка может запутаться в том, где она находится. Но если вы набираете текст /bin/pwd, он запускается в отдельном процессе, который не имеет доступа к представлению оболочки о том, что такое рабочий каталог, и поэтому он определяет истинный рабочий каталог, по старинке. (Исключение: /bin/pwdпрограмма может посмотреть на переменную окружения PWD, и, очевидно, она это делает, когда вы указываете -L.) Вот еще один пример того, как оболочка может запутаться:
cd /home/sim/aa # Предположим , что /home, /home/simи/home/sim/aa # все реальные каталоги (не символические ссылки). pwd # Вывод: /home/sim/aaчто правильно. mv ../aa ../bb pwd # Вывод: /home/sim/aaчто неверно. /bin/pwd # Вывод: /home/sim/bbчто правильно.
И, на всякий случай, если вам не ясно это, если вы печатаете ln -s . aaи cd aa, то ваш текущий рабочий каталог не изменился , больше, чем когда вы печатаете cd .- потому что, по сути, это то, что вы делаете, когда печатаете cd aa.
Спасибо, очень хороший ответ, это то, чего я ждал;)
user3581976
2
Этот ответ кажется немного согнутым . Это больше, -Lчем просто экономия затрат - и $PWDэто определяемая пользователем переменная среды, определяемая POSIX, - приложения пользовательского пространства, вероятно, должны доверять ей (что бы это ни значило ...?) . В любом случае, хотя я вовсе не фанат символических ссылок, это является прерогативой пользователя косвенно использовать столько сумасшедших указаний, сколько ему или ей следует выбирать с ними - и это то, что -Lважнее всего.
mikeserv
1
Это должен быть принятый ответ (символические ссылки не являются предметом вопроса).
/bin/pwd
по умолчанию игнорирует символическую ссылку, прочитайте частьinfo pwd
в моем ответе: Напечатайте полностью разрешенное имя для текущего каталога. То есть все компоненты напечатанного имени будут фактическими именами каталогов - ни один не будет символическойset -o physical
, теперь по умолчаниюpwd
является-P
опцией использования , если у вас нет-L
опции, как вы печатаете путь, содержащий символьную ссылку? Прочитайте это,https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
чтобы узнать, чтоset -o physical
делает.Для процесса возможно опросить файловую систему, чтобы определить ее текущий рабочий каталог, используя метод, который является слишком сложным, чтобы быть в теме в качестве ответа на этот вопрос. Это то, что делают
pwd
программа иgetcwd
функция библиотеки. На заре Unix они были единственными способами узнать, каков ваш рабочий каталог. Вот часть ответа на ваш вопрос, которую я не могу найти ни в одном из других ответов или даже где-либо еще на этом сайте (после 42-секундного поиска):getcwd
).После этого, всякий раз , когда вы делаете
cd
,pushd
илиpopd
, оболочка отслеживает рабочий каталог с помощью функции манипулирования строк. Например,/home/sim
и вы печатаетеcd ..
, оболочка вычисляет, что ваш рабочий каталог/home
./home/sim
и вы печатаетеcd .
, оболочка вычисляет, что ваш рабочий каталог все еще/home/sim
./home/sim
и вы печатаетеcd aa
, оболочка вычисляет, что ваш рабочий каталог/home/sim/aa
- без проверки,aa
является ли символическая ссылка.Это позволяет сэкономить на стоимости звонков
getcwd
. Но это компромисс, поскольку он может привести к неверной информации.pwd
(встроенная) просто отображает запомненное / вычисленное представление оболочки о том, что является рабочим каталогом.Итак, суть в том, что оболочка может запутаться в том, где она находится. Но если вы набираете текст
/bin/pwd
, он запускается в отдельном процессе, который не имеет доступа к представлению оболочки о том, что такое рабочий каталог, и поэтому он определяет истинный рабочий каталог, по старинке. (Исключение:/bin/pwd
программа может посмотреть на переменную окружения PWD, и, очевидно, она это делает, когда вы указываете-L
.) Вот еще один пример того, как оболочка может запутаться:И, на всякий случай, если вам не ясно это, если вы печатаете
ln -s . aa
иcd aa
, то ваш текущий рабочий каталог не изменился , больше, чем когда вы печатаетеcd .
- потому что, по сути, это то, что вы делаете, когда печатаетеcd aa
.источник
-L
чем просто экономия затрат - и$PWD
это определяемая пользователем переменная среды, определяемая POSIX, - приложения пользовательского пространства, вероятно, должны доверять ей (что бы это ни значило ...?) . В любом случае, хотя я вовсе не фанат символических ссылок, это является прерогативой пользователя косвенно использовать столько сумасшедших указаний, сколько ему или ей следует выбирать с ними - и это то, что-L
важнее всего.