Я пишу библиотеку для манипулирования строками пути Unix. В таком случае мне нужно понять несколько неясных моментов синтаксиса, о которых большинство людей не будут беспокоиться.
Например, как лучше , как я могу сказать, это , кажется , что foo/bar
и foo//bar
как указывают на то же место.
Кроме того, ~
обычно обозначает домашний каталог пользователя, но что, если он появляется в середине пути? Что происходит потом?
На эти и несколько десятков других непонятных вопросов нужно ответить, если я собираюсь написать код, который правильно обрабатывает все возможные случаи. Кто-нибудь знает точную ссылку, которая объясняет точные правила синтаксиса для этого материала?
(К сожалению, поиск таких терминов, как «Синтаксис пути Unix» просто приводит к миллиону страниц, обсуждающих $PATH
переменную ... Черт, я даже изо всех сил пытаюсь найти подходящие теги для этого вопроса!)
~
) посвящена тому, как linux обрабатывает несколько разделителей пути (/ home //// username /// file) . Ближе всего к нормативной справке будет спецификация POSIX или Single Unix - нелегкое чтение.Ответы:
Есть три типа путей:
foo
,foo/bar
,../a
,.
. Они не начинаются с/
и относятся к текущей директории процесса, выполняющего системный вызов с этим путем./
,/foo/bar
или///x
. Они начинаются с 1 или 3 или более/
, они не являются относительными, ищутся, начиная с/
корневого каталога.//foo
лечиться специально, но не указывает как. Некоторые системы используют это для особых случаев, таких как сетевые файлы . Это должно быть ровно 2 слеша.За исключением начала, последовательности косых черт действуют как единое целое.
~
является особенным только для оболочки , он расширяется оболочкой, он не является особенным для системы. То, как оно расширяется, зависит от оболочки. Оболочки выполняют другие формы расширений, такие как globbing (*.txt
) или расширение переменных/$foo/$bar
или другие. Что касается системы, то~foo
это просто относительный путь, подобный_foo
илиfoo
.Что нужно иметь в виду:
foo/
это не то же самое, чтоfoo
. Это ближе кfoo/.
чемfoo
(особенно еслиfoo
это символическая ссылка) для большинства системных вызовов на большинстве систем (foo//
то же самое, что иfoo/
если).a/b/../c
не обязательно совпадает сa/c
(например, еслиa/b
является символической ссылкой). Лучше не лечить..
специально.a/././././b
таким же, какa/b
если бы.источник
/
,.
и..
(?)//foo
обработки в Cygwin, где он используется для путей UNC . Это//server/share/dir/file.txt
допустимый путь, который по умолчанию указывает вне системы. Cygwin возвращается к локальной системе, если не может найтиserver
.Да. Это часто встречается, потому что программное обеспечение иногда объединяет путь, предполагая, что первая часть не заканчивалась прямой косой чертой, поэтому добавляется одна, чтобы убедиться (это может означать, что их может быть два или более).
foo///bar
аfoo/////bar
также указать на то же место, что иfoo/bar
. Хорошая функция для библиотеки манипулирования путями - это та, которая уменьшает любое количество последовательных слешей до одного (кроме как в начале пути, где она может использоваться в виде URL-адреса, или, как указывает Стефан, для любого не указано специального назначения).Это преобразование выполняется через оболочку и тильду , которая работает, только если она является первым символом в пути. Нужно ли вам иметь дело с этим, зависит от контекста. Если библиотека должна использоваться с обычными программами, которые получают, например, аргументы командной строки, содержащие путь, раскрытие тильды уже выполняется, когда они видят путь. Единственная ситуация, в которой я вижу, это проблема, если вы обрабатываете пути непосредственно из текстового файла.
Кроме того, он
~
является допустимым символом в пути * nix и не должен быть изменен ни на что другое. В соответствии с этим , единственными символами, которые не являются допустимыми в имени файла Unix, являются/
(потому что это разделитель пути) и «ноль» (или нулевой байт), потому что они вообще недопустимы в тексте.источник
//
что технически это тоже не так. Как URL-адреса, так и более новые, в соответствии с SC, свободно неоднозначные спецификации POSIX для//
могут быть получены из таких, и в этом случае «URL-ish» кажется подходящей меткой для соглашения (даже если UNCs старше, и даже если подобие непреднамеренно). Я бы никогда не сказал, что «они являются URL-адресами», только это//
или\\
служит цели «URL-адреса».