В чем разница между «realpath» и «readlink -f»

68

Я много читал о realpathкоманде и о том, как она устарела, readlink -fпоскольку сейчас рекомендуется. В некоторых местах я также видел, что причина, по которой был введен realpath, заключалась в отсутствии такой функциональности в readlink, и что после того, как он был введен, realpath больше не был необходим, и его поддержка прекращалась большинством поставщиков ОС.

Причина моего вопроса в том, что я также видел, как многие люди рекомендуют readlink -fв качестве команды «очень похожую» realpath, и это то, что беспокоит меня, потому что никто не уточняет эту «очень похожую» часть. Каковы фактические различия?

Фелипе Леан
источник

Ответы:

73

Есть несколько realpathкоманд вокруг.

realpathУтилита является оболочкой вокруг realpathбиблиотеки функций и была заново много раз .

Debian используется для поддержания realpathпакета ( отделенного от dwwwтак древесного ) , который не изменился , за исключением относительно упаковки и документации с 2001 года, но в настоящее время прекращено. Эта утилита устарела, потому что теперь существует больше стандартных альтернатив (GNU readlinkи скоро GNU realpath), но в то время утилит GNU даже не было readlinkвообще. Эта реализация realpathподдерживает несколько optionsдля предотвращения разрешения символьных ссылок или для вывода с нулевым символом в конце. BusyBox также включает в себя свою собственную realpathкоманду (которая не имеет никакой опции).

GNU coreutils представила realpathкоманду в версии 8.15 в январе 2012 года. Это совместимая замена для BusyBox и Debian realpath, а также имеет много общих с GNU опций readlink.

realpathимеет тот же эффект, что и readlink -fс GNU readlink. Что отличает две команды (или, скорее, от различных realpathкоманд readlink -f), это дополнительные опции, которые они поддерживают.

GNU realpathне считается устаревшим; у него противоположная проблема: он слишком новый, чтобы быть доступным везде. Debian обычно опускал GNUrealpath из своего coreutilsпакета и придерживался собственного realpath. Я не знаю почему, так как GNU realpathдолжен быть заменой. Однако в Debian jessie и Ubuntu 16.04 используется GNU realpath.

В настоящее время в системах Linux лучше всего канонизировать путь, который может содержать символические ссылки readlink -f.

В системах BSD есть readlinkкоманда, отличающаяся от GNU readlink. В частности, BSD readlinkне имеет возможности канонизировать пути, он только проходит символическую ссылку, переданную ему.

readlinkМежду прочим, была такая же проблема - она ​​также была изобретена много раз (исключение этой утилиты, когда символические ссылки были добавлены в Unix, было прискорбным упущением). В настоящее время он стабилизировался в нескольких реализациях со многими несовместимыми флагами (в частности, BSD против GNU).

Жиль "ТАК - перестань быть злым"
источник
8
readlink -fбыл в OpenBSD задолго до GNU. Все NetBSD, FreeBSD и OpenBSD теперь есть readlink -f(ваша ссылка даже упоминает об этом). realpathбыл в FreeBSD и IRIX в течение долгого времени (не знаю, предшествует ли он Debian). HPUX и IRIX тоже есть readlink, хотя и нет -f. realpathПакет в Debian экспериментальной теперь один из Coreutils ( в качестве эксперимента , чтобы увидеть , если он ломает вещи). Dwww realpathдействует больше как readlink -eGNU, readlink -fтак что это не полная замена
Стефан Шазелас
2
realpathбыла в FreeBSD с 2002 года До этого, pwdделает это (начиная с 2000 года, pwd some-fileназвали бы realpath()на file). Debian имел realpathпакет с 1996 годом один на IRIX , вероятно , предшествующий его , хотя я не нашел никаких других доказательств , чем это было в IRIX 6.5 в 1998 году OpenBSD купороса добавилось -fк readlink в 1997 году . GNU добавили readlinkв 2003 году, и это было -fс самого начала.
Стефан Шазелас
2
Отличное резюме спасибо. Обратите внимание, что лучшая ошибка в запросе Debian на переключение на вариант GNU - bugs.debian.org/730779 Даже существующий сопровождающий realpath хочет, чтобы это произошло
Pádraig Brady
1
Потрясающий ответ. Пропущены только ссылки на реализацию RHEL realpath. Кто-нибудь знает, отличается ли он от readlink -fверсии?
Фелипе Леау,
1
@ StéphaneChazelas Ого, в моих ответах действительно много ошибок. Спасибо за указание на них. Не могли бы вы опубликовать правильный ответ, а я удалю свой? (В противном случае, я исправлю ошибки, но это больше работы, чтобы привязаться к моему длинному списку задач ...)
Жиль "ТАК - перестать быть злым"
17

tl; dr readlink -f вернется 0для несуществующего файла в существующей директории, тогда как realpathвернется 1. Тем не менее, readlink -eбудет вести себя как realpathи вернуть 1для несуществующего файла (см. Примечание редактора в конце).

readlink -f

$ readlink -f non-existent-file
/home/user/non-existent-file
$ echo $?
0

readlink -e

$ readlink -e non-existent-file
$ echo $?
1

realpath

$ realpath non-existent-file
non-existent-file: No such file or directory
$ echo $?
1

readlink -f с несуществующим каталогом

readlink -f поведение варьируется в зависимости от того, какая часть пути не существует.

$ readlink -f /tmp/non-existent-dir/foo
$ echo $?
1

за доступностью

readlinkустанавливается в большинстве дистрибутивов Linux. Принимая во внимание, что realpathчасто должны быть явно установлены.

В итоге

Если вы хотите заменить звонки, realpath ...используйте readlink -e ....


Протестировано с readlink (GNU coreutils) 8.21 и realpath версии 1.19 на Ubuntu 16.

( Ред .: @AnthonyGeoghegan пишет: « это относится к версии Debian realpath. Версия GNU realpathведет себя так же, как иreadlink -f »)

JamesThomasMoon1979
источник
3
Я проголосовал за этот ответ, но я бы предложил уточнить, что это относится к версии Debian realpath. Версия GNU realpathведет себя так же, как и readlink -f.
Энтони Дж - правосудие для Моники
2
Можно подтвердить, что это не работает на MacOS High Sierra.
Пред