Конечные косые черты на символических ссылках на каталоги

8

Я пытаюсь эмулировать процесс разрешения пути (см. Man-страницу path_resolution) в Unix-подобных системах.

Моя ОС Linux с ядром GNU 8.7.

Чтобы прояснить значение дополнительного трейлинга «/» в резолюции, я сделал следующие вещи в оболочке:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Все было хорошо, потому что this_is_link является символической ссылкой, и я просто удалил ее. Но пока пытаюсь:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

Это повторилось rm: cannot remove 'this_is_link/': Is a directory

Ну, после «/» последовала символическая ссылка, подумал я. Итак, я попробовал другую команду:rmdir this_is_link/

И вышел забавный результат: rmdir: failed to remove 'this_is_link/': Not a directory

Не то, что я ожидал. Поэтому я попросил моего друга подтвердить, можно ли получить такой же результат в его системе. У него была более низкая версия coreutils, чем у меня. И результат не был удивителен, независимо от того , rmили rmdir 'this_is_link/', такая же ошибка Not a directoryпроисходит .

А другой друг только что опробовал его на своей Mac OS, результат: rm=> 'Является ли каталог', rmdir=> каталог успешно удален, ссылка осталась .

Есть ли какие-либо спецификации о точном поведении разрешения пути?

ymfoi
источник

Ответы:

7

Спецификация POSIX / Single Unix указывает, что имя пути с косой чертой должно ссылаться на каталог (см. Базовые определения §4.11 разрешение пути ). foo/на самом деле определяется как эквивалент foo/.(для целей разрешения пути, а не при манипулировании именами файлов basenameи dirnameигнорирует завершающие косые черты). Большинство реализаций уважают это, но есть несколько исключений.

Это объясняет поведение rm this_is_link/: это эквивалентно тому rm this_is_link/., где аргумент явно является каталогом.

rmdir this_is_link/Аналогично следует обратиться к каталогу. То, чего нет на вашей машине, является ошибкой в ​​GNU coreutils. OSX ведет себя правильно здесь.

Жиль "ТАК - перестань быть злым"
источник
Это именно то, что мне нужно, спасибо, парень!
ymfoi
-1

Мой дубль:

  • '' rm link / '' завершается неудачно, потому что rm смотрит на последний символ, видит, что это косая черта, дает (не совсем правильную) диагностику, которую вы видели;
  • '' rmdir link / '' не работает нормально: ссылка не является каталогом, это символическая ссылка
  • '' ссылка rm '' будет успешно выполнена

Кстати, разрешение пути очень мало связано с этим, просто кажется, что '' rm '' обрезает угол, а не (правильно) вызывает stat для аргумента (что и делает rmdir).

Приветствия.

Инопланетная Форма Жизни
источник
1
На самом деле, обратное кажется правдивым: rmвызывает stat (ну, собственно, newfstatat с AT_SYMLINK_NOFOLLOWопцией) и отказывается продолжать, тогда как rmdir фактически вызывает rmdir (2), но получает ENOTDIR.
Ансгар Эстерманн
@AnsgarEsztermann AT_SYMLINK_NOFOLLOWбудет препятствовать тому, чтобы он следовал по символической ссылке, поэтому rm должен удалить саму ссылку вместо вывода «Not a directory», что не соответствует обстоятельствам.
ymfoi
После краткой проверки с помощью stat (1) косая черта заменит опцию. Вывод statи stat -Lотличается только в том случае, если аргумент задан без завершающего слеша.
Ансгар Эстерманн
@AnsgarEsztermann О, я вижу ... Спасибо. Как насчет различных воздействий на различную окружающую среду? Любые идеи?
ymfoi
1
Наоборот, на машине ymfoi rmведет себя правильно, а rmdirне так. Трейлинг /должен заставить их обрабатывать свои аргументы как каталог, в соответствии со стандартом POSIX. Смотрите мой ответ для ссылок .
Жиль "ТАК ... перестать быть злым"