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

sudo считает переменную среды, SUDO_ASKPASS, если это не работает от терминала (как в Вашем случае) или если-A установлен. Это использует это в качестве команды для выполнения для получения пароля. Например:

echo -e '#!/bin/sh\nhead -n 1' > ~/bin/reader
chmod a+x ~/bin/reader
export SUDO_ASKPASS="$HOME/bin/reader"
sudo -A echo "I'm root\!"

Предложит Вам пароль на stdin и не потребует терминала.

В конкретном случае того, что Вы пытаетесь сделать однако, могло бы быть лучше позволить корневой вход в систему SSH, но только с ключом SSH и командой, ограниченной rsync. Существует хороший ресурс на этом здесь.

3
31.07.2014, 18:59
3 ответа

. не является встроенной оболочкой (или любой другой оболочкой). В каждом каталоге есть записи . и ... . Вы можете проверить это с помощью cd'ing на какой-нибудь произвольный каталог и сделать ls -lia . Вы увидите . и ... записей. Я попросил Вас использовать флаг '-i' на ls, чтобы получить номера входов: запишите их для . и ... . Идите вверх по каталогу, но делая cd ... или cd /something/soemthingelse/whateverever. Сделайте ls -lia снова. Заметьте, что кодный номер . идентичен номеру ... в вашем первом списке. В каждом каталоге есть каталоги, которые были созданы, с именами "..." и "...". Запись "..." имеет тот же самый номер в коде, что и имя каталога в родительской директории. Запись "..." всегда является родительской директорией. Если вы сделаете ls -li /, вы увидите, что "..." и "..." имеют одно и то же значение.

Эта конвенция устраняет необходимость специального кода для ссылки на текущую директорию: она всегда называется "...". Это устраняет необходимость использования специального кода для "перехода вверх по одной директории": всегда "...". Единственные специальные случаи - это корневая директория и сетевые файловые системы. Корень файловой системы имеет "..." и "..." с одинаковым номером в коде, не отличающимся. Смонтированные по сети файловые системы имеют разрывы во входных номерах в точке монтирования, и поведение зависит от того, что такое удаленная файловая система и какой протокол используется для монтирования.

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

8
27.01.2020, 21:08

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: -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
3
27.01.2020, 21:08

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

Кстати, чтобы немного расширить ответ Gnouc , в выпуске 6 базовых спецификаций Open Group в переменных среды говорится:

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

С другой стороны, если вы запустите внешнюю команду / bin / pwd , вы получите новое имя текущего каталога. Почему так происходит? Команда pwd из coreutils выполняет некоторые проверки корректности переменной среды 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 Запуск типа pwd может подтвердить это.

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

5
27.01.2020, 21:08

Теги

Похожие вопросы