Intereting Posts

Как сделать pwd и. определить текущий путь по-разному?

Это в основном потому, что pwd не является встроенным, а . встроен в оболочку bash?

Например, они различаются в следующем примере:

 /tmp/ttt$ mv ../ttt ../tttt /tmp/ttt$ pwd /tmp/ttt /tmp/ttt$ cd . /tmp/tttt$ 

. не является встроенным bash (или любой другой оболочкой). Каждый каталог имеет записи . и .. в нем. Вы можете проверить cd'ing в какой-то произвольный каталог и выполнить ls -lia . Вы увидите . и .. записи. Я использовал флаг '-i' для ls чтобы получить номера inode: обратите внимание на них . и .. Поднимите каталог, но cd /something/soemthingelse/whatever cd .. или cd /something/soemthingelse/whatever . ls -lia . Обратите внимание, что номер inode . идентичен таковому .. в вашем первом листинге. Каждый каталог имеет каталоги в нем при создании, называемый «.». а также "..". «.» запись имеет тот же номер индекса, что и имя каталога в родительском каталоге. Запись «..» всегда является родительским каталогом. Если вы сделаете ls -li / вы увидите, что «.» и ".." имеют одинаковое значение.

Это соглашение устраняет необходимость использования специального кода случая для ссылки на текущий каталог: он всегда называется «.». Это устраняет необходимость в специальном коде кода для «перехода вверх по одному каталогу»: он всегда «..». Единственными специальными случаями являются корневой каталог и сетевые файловые системы. У корня файловой системы есть "." и ".." с тем же номером inode, не отличается. Сетевые файловые системы имеют разрывы в числах inode в точке монтирования, и поведение зависит от того, что такое удаленная файловая система, и какой протокол используется для ее монтирования.

Что касается изменения подсказки, когда вы вызывали mv ../ttt ../tttt , вы фактически переименовали рабочий каталог вашей оболочки. Вы не вызывали команду оболочки, которая проверяет рабочий каталог, пока вы не сделали cd . , поэтому промежуточный pwd сообщает старое имя /tmp/tt .

Предполагая, что вы используете Bash, который имеет pwd как встроенный 1 , происходит то, что команда cd запускает оболочку для обновления информации о текущем каталоге. Пока вы не запустите cd , оболочка будет думать, что текущий каталог не изменился, поэтому он не пытается получить свой новый путь.

Кстати, чтобы немного расширить ответ Gnouc, в разделе «Свойства базовой группы Open Group 6» по переменным окружения говорится:

PWD […] должен представлять абсолютный путь к текущему рабочему каталогу. Он не должен содержать компонентов имени файла точки или точки. Значение устанавливается утилитой cd .

С другой стороны, если вы запустите команду external /bin/pwd , вы получите новое имя текущего каталога. Почему это происходит? Команда pwd от coreutils выполняет некоторые проверки PWD переменной среды PWD и не печатает ее, если она недействительна. Подробности можно найти в исходном коде функции logical_getcwd (из версии Coreutils 8.23).

Другая команда, которую вы можете использовать для получения канонического пути текущего каталога, – это readlink -f . 2 .

 [ciupicri@host ttt]$ pwd /tmp/ttt [ciupicri@host ttt]$ mv ../ttt ../tttt [ciupicri@host ttt]$ pwd /tmp/ttt [ciupicri@host ttt]$ /bin/pwd /tmp/tttt [ciupicri@host ttt]$ readlink -f . /tmp/tttt 

1 Пуск type pwd может подтвердить это.

2 Из справочной страницы readlink : -f , --canonicalize canonicalize, следуя каждой символической --canonicalize в каждом компоненте данного имени рекурсивно; должен существовать только последний компонент.

pwd будет печатать значение $PWD если оно содержит абсолютное имя пути, которое не имеет точки . или точка-точка. Из определения POSIX pwd :

 -L If the PWD environment variable contains an absolute pathname of the current directory that does not contain the filenames dot or dot-dot, pwd shall write this pathname to standard output. Otherwise, if the PWD environment variable contains a pathname of the current directory that is longer than {PATH_MAX} bytes including the terminating null, and the pathname does not contain any components that are dot or dot-dot, it is unspecified whether pwd writes this pathname to standard output or behaves as if the -P option had been specified. Otherwise, the -L option shall behave as the -P option. 

По умолчанию pwd использует параметр -L чтобы он печатал текущее значение PWD , которое устанавливается при использовании cd . Когда вы mv текущий каталог на новый путь, PWD все равно не изменится, поэтому вы получите старый путь.

У вас может быть несколько способов получить правильный новый путь:

  • Использование опции -P : pwd -P
  • Использование /proc : ls -l /proc/self/cwd

Заметка

В качестве определения POSIX для переменной PWD , если приложение установлено или отменено значение PWD , поведение cd и pwd не определено.

 % cuonglm at /tmp/ttt % PWD=/home/cuonglm % cuonglm at ~ % pwd /tmp/ttt % cuonglm at ~ % pwd -P /tmp/ttt