Является ли `~ / Documents` относительным или абсолютным путем?

37

Это всего лишь словарный вопрос, но он постоянно крутится в моей голове.

Это происходит из практического экзамена из книги подготовки LPIC . Правильный ответ в соответствии с книгой - ~/Documentsэто относительный каталог, потому что он относительно домашнего каталога.

Тем не менее, эта книга содержит достойное соотношение опечаток и ошибок, поэтому я не могу принимать как должное все, что там написано. Здесь я не согласен, потому что для меня ~действует как переменная, расширенная оболочкой либо в содержимое $HOMEпеременной, либо в путь к текущему домашнему каталогу пользователя (см. man bash), Поэтому фактический путь - /home/myuser/Documentsэто действительно абсолютный каталог.

Даже Википедия , на этот раз, кажется, не помогает мне в этой теме (даже если кажется, что она подтверждает, что эта книга ошибочна):

Абсолютный или полный путь указывает на одно и то же место в файловой системе независимо от текущего рабочего каталога. Для этого он должен содержать корневой каталог.

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

Здесь я снова не согласен: согласно этому определению путь, /opt/kde3/bin/../libкоторый не зависит от текущего рабочего каталога, должен быть абсолютным, однако мое нынешнее понимание этого соответствует автору книги, делающему этот путь относительным.

По словам словаря Вебстера, быстрый поиск в Интернете только добавляет мне разочарования :

абсолютный путь - путь относительно корневого каталога. Его первый символ должен быть разделителем пути.

Так $HOME/Documentsили даже просто $HOMEне будет считаться абсолютными каталогами? Или это определение подразумевает расширение переменной? А как насчет ~персонажа оболочки ? Есть ли какое-нибудь надежное определение относительного или абсолютного каталога, который я могу найти где-нибудь, и я ошибаюсь полностью?

WhiteWinterWolf
источник
7
Все пути являются относительными, некоторые из них являются относительными только к корневому каталогу /, и те, которые мы называем абсолютными. Таким образом , все , что начинается от /я бы назвал абсолютным (даже если это /usr/../etc) , и все остальное , я бы назвал относительными ( ~/Doc, Doc, ../john/Doc, $HOME/..., ...). Дело в том, что абсолют должен работать независимо от текущего рабочего каталога или текущего пользователя. Относительный может работать только в некоторых конкретных узких случаях.
Джимми
6
Путь может расширяться в другое место в зависимости от того, кто является пользователем. Сказав это, на мой взгляд, это все же абсолютный путь, а не относительный путь. Хотя я не думаю, что определения абсолютного и относительного пути так точно определены. Это не математика. Этот вопрос, на самом деле, не проверяет понимание, и бессмысленно.
Фахим Митха
1
@FaheemMitha: LPIC - это независимая от дистрибутива сертификация Linux. Сама сертификация кажется хорошей, но это далеко не так (по крайней мере, некоторые) книги, проданные для подготовки к этому экзамену в качестве самостоятельной работы ...
WhiteWinterWolf
2
@jimmij: «относительный» имеет определенное техническое значение в контексте путей, и использование другого англоязычного смысла слова является плохой практикой. Я полностью не согласен с тем, чтобы называть ~/fooотносительный путь. То, что вы получаете, это разница между жестким кодированием и параметризацией. Смотрите мой ответ для более подробной информации.
Питер Кордес
1
Определения словаря Вебстера верны, но очень запутаны. Однако это означает, что такие строки, как ~/Documentsи $HOME/Documentsне являются путями. Они идентифицируют (абсолютные) пути после расширения, но сами они не являются путями. Я думаю, что это согласуется с тем, как много пользователей Unix / Linux используют этот термин, но, без сомнения, эти строки также называются путями.
reinierpost

Ответы:

41

Если автор пытался поймать вас, говоря об этой литеральной строке (без расширения оболочки) как о пути, то это относительный путь ( mkdir -p './~/Documents'). Иначе:


Это абсолютный путь , потому что его разрешение не зависит от текущего рабочего каталога процесса. Относительный путь всегда означает относительный к рабочему каталогу процесса. Или в случае целей символической ссылки, относительно расположения символической ссылки. ( gcc -> gcc-5.2против gcc -> /usr/bin/gcc-5.2). Это важно для NFS-монтирования и других случаев, когда вы можете получить доступ к одной и той же символической ссылке по разным абсолютным путям. например

/net/tesla/home/peter/foo -> bar  # always works from other machines

/net/tesla/home/peter/foo -> /home/peter/bar  # references my home dir on the local machine, not tesla.

Debian иногда устанавливает символические ../../doc/whatever/whateverссылки вместо абсолютной цели символической ссылки, поэтому он работает, когда NFS монтируется где-то еще или когда смотрит на chroot, не chroot(8)входя в него.

Каждый процесс Unix имеет свой собственный cwd. Команда pwdсуществует только для ее печати.

см. http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html для получения дополнительной информации об изменении каталогов с помощью системных вызовов POSIX.


Как и все остальные, ~расширяется оболочкой, прежде чем путь используется для чего-либо. Использование ~/bin/myprogв сценарии оболочки заставит его работать по-разному для разных пользователей. Разница между ~/bin/fooи /home/peter/bin/fooзаключается в том, что один из них жестко закодировал местоположение, а другой его параметризовал. Ошибочно (IMO) называть ~версию относительным путем.

Разговоры о вещах, относящихся к «переменной окружения», просто сбивают с толку. Это плохая практика - использовать разные англоязычные значения терминов, которые имеют конкретные технические значения в контексте, в котором вы их используете.

На сломанной системе, с HOME=a/relative/path, ~/fooрасширится до относительного пути. Это не будет полезной настройкой вообще.

Питер Кордес
источник
3
Спасибо за этот ответ, он кажется мне наиболее полным. У меня также сложилось впечатление, что автор ошибочно перепутал в этом понятие канонического пути (о чем автор нигде не упоминает). /opt/kde3/bin/../libнапример , ошибочно классифицируются как относительный путь: он является абсолютным путем , но не каноническим. Как вы сказали, это только сбивает с толку, так что спасибо за ваши разъяснения и информацию, связанную с NFS :)!
WhiteWinterWolf
1
Я должен заключить, что написание книги для подготовки к тестам не очень весело, и что люди, которые просто используют Unix или GNU / Linux для своих повседневных вычислений, не являются теми, кто пишет эти книги. Этот пример вызова неканонического относительного пути мне кажется очень плохим и очевидным. man7.org/linux/man-pages/man3/realpath.3.htmlrealpath(1)) делают обе вещи: канонизируют и делают абсолютными (а также следуют по символическим ссылкам), поэтому, возможно, возникла некоторая путаница.
Питер Кордес
2
Тем не менее, это просто обычные повседневные концепции для меня. Я думаю, что было бы странно иметь лист бумаги, в котором говорилось, что я их знаю ... Но удачи в том, чтобы ваш кусок бумаги @WhiteWinterWolf показывался всем людям, которые любят смотреть на листки бумаги. :)
Питер Кордес
48

По сути это вопрос определения терминов. Поэтому для ваших целей ответом будет то, что хочет LPIC. Но мы можем прийти к некоторым выводам, основанным на технических фактах:

Если вы перешли '~/Documents'на системный вызов , он будет искать каталог с именем точно ~в текущем каталоге (и, вероятно, сбой). Таким образом, согласно понятию путей, используемых ядром , это относительный путь, но мы не это имели в виду.

~это синтаксис, реализованный оболочкой (и другими программами, которые имитируют ее для удобства), которая расширяет его до реального имени пути. Для иллюстрации ~/Documentsпримерно то же самое, что $HOME/Documents(опять же, синтаксис оболочки). Поскольку $HOMEдолжен быть абсолютный путь, значение $HOME/Documents также является абсолютным путем. Но текст $HOME/Documentsили ~/Documentsдолжен быть расширен оболочкой, чтобы стать тем путем, который мы имеем в виду.

Таким образом , если бы я хотел , чтобы быть точным и последовательным, я бы сказал , что ~/Documentsэто фрагмент оболочки-скрипта , который расширяется к абсолютному пути.

Кевин Рид
источник
Конечно, ядро ​​понятия не имеет, что $HOMEзначит, точно так же, как оно понятия не имеет, что ~значит. Однако я нахожу утверждение, что расширение сделано оболочкой, сомнительно; большинство приложений поддерживают это, что указывает на библиотеку C, а не на оболочку. Однако расширение переменной среды является особенностью оболочки; вы можете открыть ~/somefile.odtв LibreOffice, но нет $HOME/somefile.odt, даже если LibreOffice был запущен из оболочки, в которой правильно установлен $ HOME.
CVN
5
Вы можете найти это сомнительным, сколько хотите, но это задокументировано и должно быть легко подтверждено или опровергнуто в C.
Бесполезно
6
Другие программы реализуют ~синтаксис в имитации оболочки, потому что это полезный ярлык. На самом деле я не знаю, есть ли библиотечная функция, которая выполняет расширение, но это определенно то, что делается отдельно от фактического использования пути.
Кевин Рид,
2
globи wordexpсделайте расширение тильды среди других вещей.
o11c
2
@ MichaelKjörling: несколько программ реализуют ~расширение; большинство нет. Например, если вы печатаете ls -l ~, lsпрограмма никогда не видит ~символ; он расширяется оболочкой раньшеls вызова. Если вы на самом деле проходим ~к ls, это не будет относиться к ней специально; try ls -l '~'`(который попытается перечислить файл с буквальным именем ~).
Кит Томпсон,
16

Если $HOMEесть /home/white/, ~/Documents( так же , как $HOME/Documents) расширяется оболочки (см здесь для объяснения) к /home/white/Documents, который является абсолютным путем.

Относительный путь - это путь, который не начинается с /(после расширения оболочки), например, ../Documentsилиfoo/bar

Некоторые старые снаряды не расширяются ~ (путь bash, tcsh, zshи т.д. ... делает); они будут видеть ~/Documentsкак относительный путь, начинающийся с ~; но обычно у вас нет имени каталога ~(но вы можете создать его с помощью mkdir '~', который я не рекомендую).

Василий Старынкевич
источник
Вы должны упомянуть, какие оболочки не расширяются~
Эдвард Торвальдс,
3

An абсолютный путь начинается с /(что относится к фиксировано), а относительный путь начинается с текущего каталога (и так , что она относится к изменениям как текущих изменений каталога). Большинство оболочек используют ~вначале как аббревиатуру для абсолютного пути к домашнему каталогу текущего пользователя, то ~/Documentsесть к каталогу Documentsв домашнем каталоге текущего пользователя, независимо от того, каким может быть текущий каталог. Так что это абсолютный путь.

vonbrand
источник
1

Путь может расширяться в другое место в зависимости от того, кто является пользователем. Сказав это, на мой взгляд, это все же абсолютный путь, а не относительный путь. Однако я не думаю, что определения абсолютного и относительного пути так точно определены. Это не математика. Этот вопрос, на мой взгляд, на самом деле не проверяет понимание и является бессмысленным.

Фахим Митха
источник
Определение намного больше, чем мнение. Википедия использует этот метод для общего случая, а не только для Unix: en.wikipedia.org/wiki/…
Питер Кордес
1

Использование ~ / в начале делает путь абсолютным, поскольку (по любому определению) возможность поиска документов не зависит от того, где вы находитесь в данный момент. Однако расширение выполняется оболочкой, а не ядром, поэтому, если вы используете оболочку, которая не распознает этот синтаксис (такой как / bin / sh, исходная оболочка Bourne, а не псевдоним bash), вы будете вне удачи.

Интересно, что если вы используете ~ root / вместо ~ /, оптимизация чтения $ HOME обычно не применяется, и она всегда будет принимать абсолютное значение, если / etc / passwd верен.

jrrk
источник
-1

Кажется, что в книге рассматривается точка зрения, что абсолютный путь - это любой путь, начинающийся с a /, а относительный путь - это что-нибудь еще.

Вы можете рассматривать ..и $HOMEкак похожие типы токенов. Оба компонента должны быть заменены для компонента пути, прежде чем путь преобразуется в абсолютный путь.

jl6
источник
3
Как ..что-нибудь подобное $HOME? ..может быть в начале пути, переданного непосредственно системному вызову, расширение оболочки не требуется. Такой путь не является абсолютным путем; это все еще относительно процесса cwd или местоположения символической ссылки. Если автор не пытался поймать вас, говоря об этой буквальной строке (без расширения оболочки) как о пути. Я думаю, что вы пытаетесь оправдываться за книгу, но я более склонен просто сказать, что это неправильно, и не допустить путаницы.
Питер Кордес