Jaka jest różnica między „realpath” a „readlink -f”

68

Dużo czytałem o realpathpoleceniu i o tym, jak został on przestarzały w porównaniu z readlink -fpoleceniem. Widziałem także w niektórych miejscach, że powodem wprowadzenia realpath był brak takiej funkcjonalności w readlink i że po wprowadzeniu realpath nie był już potrzebny, a większość producentów systemów operacyjnych przestała go obsługiwać.

Powodem mojego pytania jest to, że widziałem także wiele osób polecających readlink -fjako polecenie „bardzo podobne” do tego realpath, i to mnie niepokoi, ponieważ nikt nie omawia tej „bardzo podobnej” części. Jakie są rzeczywiste różnice?

Felipe Leão
źródło

Odpowiedzi:

73

Wokół jest kilka realpathpoleceń.

realpathNarzędzie jest owinięcie wokół realpathfunkcji bibliotecznych i został odkryty na nowo wiele razy .

Debian wykorzystywane do utrzymywania realpathpakiet ( oddzielony od dwwwod zdrewniałe ), które nie zmieniły się poza dotyczące opakowań i dokumentacji od 2001 roku, ale został zniesiony. To narzędzie było przestarzałe, ponieważ istnieje teraz więcej standardowych alternatyw (GNU readlinki wkrótce GNU realpath), ale w tym czasie narzędzia GNU nawet nie miały readlink. Ta implementacja realpathobsługuje kilka, optionsaby zapobiec rozdzieleniu dowiązań symbolicznych lub wygenerować wyjście zakończone zerem. BusyBox zawiera również własne realpathpolecenie (które nie ma żadnej opcji).

Coreutils GNU wprowadziło realpathpolecenie w wersji 8.15 w styczniu 2012 r. Jest to kompatybilny zamiennik dla BusyBox i Debian realpath, a także ma wiele opcji wspólnych z GNU readlink.

realpathma taki sam efekt jak w readlink -fprzypadku GNU readlink. To, co odróżnia te dwa polecenia (a raczej różne realpathod nich readlink -f), to dodatkowe opcje, które obsługują.

GNU realpathnie jest przestarzałe; ma odwrotny problem: jest zbyt nowy, aby był dostępny wszędzie. Debian zwykł pomijać GNUrealpath ze swojego coreutilspakietu i trzymać się własnego realpath. Nie wiem dlaczego, skoro GNU realpathpowinno być zamiennikiem. Jednak w Debianie jessie i Ubuntu 16.04 realpathużywany jest GNU .

W systemach Linux najlepszym rozwiązaniem do kanonizacji ścieżki, która może zawierać dowiązania symboliczne, jest obecnie readlink -f.

Systemy BSD mają readlinkpolecenie o różnych możliwościach od GNU readlink. W szczególności BSD readlinknie ma opcji kanonizacji ścieżek, jedynie przegląda przekazane do niej dowiązanie symboliczne.

readlink, nawiasem mówiąc, miał ten sam problem - został również wynaleziony wiele razy (nie dodawanie tego narzędzia, gdy dowiązania symboliczne były dodawane do Uniksa, było godnym pożałowania pominięciem). Teraz ustabilizował się w kilku implementacjach z wieloma niezgodnymi flagami (w szczególności BSD vs. GNU).

Gilles
źródło
8
readlink -fbył w OpenBSD na długo przed GNU. Wszystkie NetBSD, FreeBSD i OpenBSD mają teraz readlink -f( nawet twój link o tym wspomina). realpathbył w FreeBSD i IRIX od dłuższego czasu (nie wiem, czy poprzedza ten w Debianie). HPUX i IRIX również readlink, choć nie -f. realpathPakiet w experimental Debian jest obecnie jednym z coreutils (jako eksperyment, aby zobaczyć czy łamie rzeczy). Dwww realpathdziała bardziej jak readlink -eGNU, readlink -fwięc nie jest to całkowite dropin zamień
Stéphane Chazelas
2
realpathzostał w FreeBSD od roku 2002. Wcześniej pwdrobił to (od 2000, pwd some-filenazwałbym realpath()na file). Debian ma realpathpakiet od 1996 roku. Ten na IRIX prawdopodobnie go poprzedza, chociaż nie znalazłem innych dowodów niż w IRIX 6.5 w 1998 roku. OpenBSD dodał -fdo niego readlink w 1997 roku . GNU dodano readlinkw 2003 roku i tak było -fod samego początku.
Stéphane Chazelas,
2
Doskonałe podsumowanie dzięki. Zauważmy, że lepszym błędem dla prośby o zmianę Debiana na wariant GNU jest bugs.debian.org/730779 Nawet istniejący opiekun realpath chce, aby zmiana nastąpiła
Pádraig Brady
1
Świetna odpowiedź. Brakowało tylko odniesień do implementacji RHEL realpath. Czy ktoś wie, czy to w jakiś sposób różni się od readlink -fwersji?
Felipe Leão
1
@ StéphaneChazelas O rany, naprawdę wiele błędów w moich odpowiedziach. Dzięki za wskazanie ich. Czy możesz podać poprawną odpowiedź, a ja usunę moją? (W przeciwnym razie poprawię błędy, ale zajmuję się dłuższą listą rzeczy do zrobienia…)
Gilles
17

tl; dr readlink -f zwróci 0nieistniejący plik w istniejącym katalogu, podczas gdy realpathzwraca 1. Jednak readlink -ebędzie się zachowywał jak realpathi powrócić 1do nieistniejącego pliku (patrz notatka Editors na końcu).

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 z nieistniejącym katalogiem

readlink -f zachowanie różni się w zależności od tego, która część ścieżki nie istnieje.

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

Dostępność

readlinkjest zainstalowany w większości dystrybucji Linuksa. Podczas gdy realpathczęsto musi być jawnie zainstalowany.

W podsumowaniu

Jeśli chcesz zastąpić połączenia, realpath ...użyj readlink -e ....


Testowany z readlink (GNU coreutils) 8.21 i realpath wersja 1.19 na Ubuntu 16.

( Wyd .: @AnthonyGeoghegan napisał „ dotyczy to wersji Debiana realpath. Wersja GNU realpathzachowuje się tak samo jakreadlink -f ”)

JamesThomasMoon1979
źródło
3
Poparłem tę odpowiedź, ale sugeruję wyjaśnienie, że odnosi się ona do wersji Debiana realpath. Wersja GNU realpathzachowuje się tak samo jak readlink -f.
Anthony Geoghegan
2
Potwierdza, że ​​to nie działa na MacOS High Sierra.
Pred