Дивна різниця між pwd та / bin / pwd


15

Я додав символьне посилання до поточного каталогу з ln -s . aa. Якщо я виконую cd aa, а після цього виконую , pwdвідповідь є /home/sim/aa.

Але якщо я виконую /bin/pwdйого, він друкує /home/sim(поточний каталог не змінився).

Звідки ця різниця?

Відповіді:


17

У більшості снарядів, включаючи баш, pwdє вбудована оболонка:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

Якщо ви використовуєте /bin/pwd, ви повинні використовувати -Lопцію, щоб отримати той же результат, що і вбудований pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

За замовчуванням /bin/pwdігнорує символьні посилання та друкує фактичний каталог.

Від info pwd:

`-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встановлений вбудований ввімкнено.

Від man bash:

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.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.

Я не впевнений, що розумію, звідки беруться ці відмінності
user3581976,

/bin/pwdза замовчуванням ігнорує символьне посилання, читає частину info pwdмоєї відповіді: Друк повністю розв'язаного імені для поточного каталогу. Тобто всі компоненти друкованого імені будуть фактичними іменами каталогів - жоден не буде символічним посиланням.
cuonglm

@ user3581976: Дивіться моє оновлення для більш чіткого.
cuonglm

Чому існує команда -L для pwd, хоча вона встановлена ​​за замовчуванням? І чи не оболонка використовує команду / bin / pwd для запуску pwd?
користувач3581976

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).
  • Після цього, коли ви робите a 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
Це має бути прийнятою відповіддю (символічні посилання - це не питання).
Томас Дікі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.