W systemie Linux readlink
narzędzie akceptuje opcję, -f
która następuje po dodatkowych linkach. Wydaje się, że to nie działa na komputerach Mac i systemach opartych na BSD. Jaki byłby odpowiednik?
Oto kilka informacji debugowania:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
readlink
może to być polecenie wbudowane lub polecenie zewnętrzne.touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile
... w moim przypadku widzę: / Users / cito / myfile`. Dodałem to do mojej odpowiedzi poniżej. Twoje zdrowie.Odpowiedzi:
readlink -f
robi dwie rzeczy:Jeśli chcesz, możesz po prostu zbudować skrypt powłoki, który używa waniliowego zachowania readlink, aby osiągnąć to samo. Oto przykład. Oczywiście możesz wstawić to do własnego skryptu, do którego chcesz zadzwonić
readlink -f
Pamiętaj, że nie obejmuje to obsługi błędów. Szczególnie ważne jest to, że nie wykrywa cykli dowiązań symbolicznych. Prostym sposobem na zrobienie tego byłoby policzenie, ile razy ominąłeś pętlę i nie powiodło się, jeśli trafisz nieprawdopodobnie dużą liczbę, na przykład 1000.
EDYCJA użyć
pwd -P
zamiast$PWD
.Zauważ, że ten skrypt oczekuje, że zostanie wywołany jak
./script_name filename
, nie-f
, zmień$1
na,$2
jeśli chcesz mieć możliwość korzystania z-f filename
podobnego linku do odczytu GNU.źródło
foo -> /var/cux
, tofoo/bar
nie zostanie rozwiązany, ponieważbar
nie jest to link, chociaż takfoo
jest.cd "$(dirname "$TARGET_FILE")"
iTARGET_FILE=$(readlink "$TARGET_FILE")
iTARGET_FILE=$(basename "$TARGET_FILE")
w odpowiednich miejscach w powyższym kodzie.MacPorts i Homebrew zapewniają pakiet coreutils zawierający
greadlink
(readlink GNU). Podziękowania dla posta Michaela Kallweitta na mackb.com.źródło
.bashrc
:export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
pwd -P
i tymreadlink
na OS X, bez instalowania czegokolwiekPATH
. Czy powyższe zaczyna się odbrew install <package> --default-names
. Wiele razy na pytanie na tej stronie udzielono niewielkiej odpowiedzi, lub więcej, poza technicznymi wymaganiami pytającego, ale w podobnej sytuacji i nadal było bardzo pomocne. topbug.net/blog/2013/04/14/…Możesz być zainteresowany
realpath(3)
Pythonemos.path.realpath
. Te dwa nie są dokładnie takie same; wywołanie biblioteki C wymaga istnienia komponentów ścieżki pośredniej, podczas gdy wersja Python nie.Wiem, że powiedziałeś, że wolisz coś lżejszego niż inny język skryptowy, ale na wypadek, gdyby kompilacja pliku binarnego była niemożliwa, możesz użyć Pythona i ctypów (dostępnych w Mac OS X 10.5) do zawinięcia wywołania biblioteki:
Jak na ironię, wersja C tego skryptu powinna być krótsza. :)
źródło
realpath
rzeczywiście tego chcę. Ale wydaje się dość niezręczne, że muszę skompilować plik binarny, aby uzyskać tę funkcję ze skryptu powłoki.readlink
, prawda?)python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"
działa ze ścieżkami typu'~/.symlink'
perl -MCwd=abs_path -le 'print abs_path readlink(shift);'
do mojej odpowiedzi :-)Nienawidzę nakładać na siebie kolejnej implementacji, ale potrzebowałem a) przenośnej implementacji czystej powłoki ib) pokrycia testem jednostkowym , ponieważ liczba przypadków brzegowych dla czegoś takiego nie jest banalna .
Zobacz mój projekt na Github dla testów i pełnego kodu. Poniżej znajduje się streszczenie implementacji:
Jak trafnie zauważa Keith Smith,
readlink -f
robi dwie rzeczy: 1) rozwiązuje rekursywnie dowiązania symboliczne i 2) kanonizuje wynik, stąd:Po pierwsze, implementacja translatora symlink:
Pamiętaj, że jest to nieco uproszczona wersja pełnej implementacji . Pełna implementacja dodaje małą kontrolę cykli dowiązań symbolicznych , a także nieco masuje dane wyjściowe.
Na koniec funkcja kanonizacji ścieżki:
To mniej więcej tyle. Wystarczająco prosty do wklejenia do skryptu, ale na tyle podstępny, że oszalałbyś na punkcie dowolnego kodu, który nie ma testów jednostkowych dla twoich przypadków użycia.
źródło
local
słowa kluczowego innego niż POSIXreadlink -f
anirealpath
. Zakładając komputer Mac z zainstalowaną formułą coreutils (więc zgreadlink
dostępną), spróbuj tego zln -s /tmp/linkeddir ~/Documents
;greadlink -f /tmp/linkeddir/..
wypisuje twój katalog domowy (rozwiązał/tmp/linkeddir
link przed zastosowaniem..
nadrzędnego katalogu referencyjnego), ale twój kod tworzy,/private/tmp/
jak/tmp/linkeddir/..
nie jest dowiązaniem symbolicznym, ale-d /tmp/linkeddir/..
jest prawdą i dlategocd /tmp/linkeddir/..
zabiera cię do/tmp
, którego kanoniczną ścieżką jest/private/tmp
.realpath -L
Zamiast tego Twój kod robi to , co robi.Prosty liniowiec w Perlu, który z pewnością działa prawie wszędzie bez żadnych zewnętrznych zależności:
Odrzuci dowiązania symboliczne.
Użycie w skrypcie może wyglądać następująco:
źródło
-l
, na przykładperl -MCwd -le 'print Cwd::abs_path shift' ~/non-absolute/file
greadlink to readlink gnu, który implementuje -f. Możesz używać Macports i innych, wolę homebrew.
źródło
Zrobiłem osobiście skrypt o nazwie realpath, który wygląda trochę jak:
źródło
sys.argv[1]
jeśli chcesz, aby skrypt wypisał rzeczywistą ścieżkę pierwszego argumentu.sys.argv[0]
po prostu drukuje prawdziwą ścieżkę samego skryptu pyton, co nie jest zbyt przydatne.~/.profile
:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'"
readlink -f
, oto zmodyfikowana wersja aliasu @jwhitlock do obsługi ewentualnej-f
flagi:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[2] if sys.argv[1] == \"-f\" else sys.argv[1])'"
A co z tym?
źródło
../../../
->/
/usr/bin/
takie jak na przykładalternatives
system.Tutaj jest przenośnym funkcja powłoki, które powinny pracować w JAKAŚ Bourne porównywalną powłokę. Rozwiąże względną interpunkcję ścieżki „.. lub”. i dereferencyjne dowiązania symboliczne.
Jeśli z jakiegoś powodu nie masz polecenia realpath (1) lub readlink (1), można to zmienić.
Cieszyć się:
także, na wypadek, gdyby ktoś był zainteresowany tym, jak zaimplementować basename i dirname w 100% czystym kodzie powłoki:
Zaktualizowaną wersję tego kodu powłoki można znaleźć na mojej stronie Google: http://sites.google.com/site/jdisnard/realpath
EDYCJA: Ten kod jest licencjonowany na warunkach licencji 2-klauzulowej (styl FreeBSD). Kopię licencji można znaleźć, postępując zgodnie z powyższym hiperłączem do mojej witryny.
źródło
FreeBSD i OSX mają wersję
stat
pochodzącą z NetBSD.Możesz wyregulować wyjście za pomocą przełączników formatu (patrz strony podręcznika pod powyższymi linkami).
Niektóre wersje OS X
stat
mogą nie mieć-f%R
opcji formatów. W takim przypadku-stat -f%Y
może wystarczyć.-f%Y
Wariant pokazuje cel, podczas gdy miejsce linku-f%R
pokazuje absolutnym ścieżka odpowiadającego plikowi.EDYTOWAĆ:
Jeśli możesz używać Perla (Darwin / OS X jest instalowany z najnowszymi wersjami
perl
), to:będzie działać.
źródło
R
Opcja-f%
brakuje. Prawdopodobniestat -f%Y
daje pożądaną wydajność. Dostosuję odpowiedź. Zauważ, żestat
narzędzie pojawiło się we FreeBSD w wersji 4.10 i NetBSD w wersji 1.6.Najprostszym sposobem rozwiązania tego problemu i włączenia funkcji readlink na Macu z zainstalowanym Homebrew lub FreeBSD jest zainstalowanie pakietu „coreutils”. Może być również konieczne w niektórych dystrybucjach Linuksa i innych systemach operacyjnych POSIX.
Na przykład w FreeBSD 11 zainstalowałem, wywołując:
# pkg install coreutils
W systemie MacOS z Homebrew polecenie wyglądałoby następująco:
$ brew install coreutils
Nie jestem pewien, dlaczego inne odpowiedzi są tak skomplikowane, to wszystko. Pliki nie są w innym miejscu, po prostu nie są jeszcze zainstalowane.
źródło
brew install coreutils --with-default-names
być bardziej specyficznym. Albo skończysz na „greadlink” zamiast…pwd -P
jest dość proste, ale znika wśród wielu innych odpowiedzi, w tym powtarzających się, stąd opinia negatywna.Rozpocznij aktualizację
Jest to tak częsty problem, że stworzyliśmy bibliotekę Bash 4 do bezpłatnego użytku (licencja MIT) o nazwie realpath-lib . Ma to na celu domyślną emulację readlink -f i obejmuje dwa pakiety testowe do sprawdzenia (1), czy działa on dla danego systemu unix i (2) względem readlink -f, jeśli jest zainstalowany (ale nie jest to wymagane). Ponadto można go używać do badania, identyfikowania i rozwijania głębokich, zepsutych dowiązań symbolicznych i odnośników cyklicznych, dzięki czemu może być użytecznym narzędziem do diagnozowania głęboko zagnieżdżonych problemów fizycznych lub symbolicznych katalogów i plików. Można go znaleźć na stronie github.com lub bitbucket.org .
Zakończ aktualizację
Kolejnym bardzo kompaktowym i wydajnym rozwiązaniem, które nie polega na niczym innym, jak na Bash, jest:
Obejmuje to również ustawienie środowiska,
no_symlinks
które umożliwia rozpoznawanie dowiązań symbolicznych do systemu fizycznego. Tak długo, jak długono_symlinks
jest to ustawione, tzn.no_symlinks='on'
Wtedy dowiązania symboliczne będą rozstrzygane w systemie fizycznym. W przeciwnym razie zostaną zastosowane (ustawienie domyślne).Powinno to działać na każdym systemie, który udostępnia Bash, i zwróci kod wyjścia zgodny z Bash do celów testowych.
źródło
Jest już wiele odpowiedzi, ale żadna nie działała dla mnie ... Więc teraz tego używam.
źródło
$target
jest ścieżką, działa tylko, jeśli jest to plik.Leniwy sposób, który działa dla mnie,
źródło
Lepiej późno niż wcale. Byłem zmotywowany do opracowania tego specjalnie, ponieważ moje skrypty Fedory nie działały na komputerze Mac. Problemem są zależności i Bash. Komputery Mac nie mają ich, a jeśli tak, to często znajdują się gdzie indziej (inna ścieżka). Manipulowanie ścieżkami zależności w wieloplatformowym skrypcie Bash to w najlepszym wypadku ból głowy, aw najgorszym przypadku zagrożenie bezpieczeństwa - najlepiej, jeśli to możliwe, unikać ich używania.
Poniższa funkcja get_realpath () jest prosta, skoncentrowana na Bash i nie są wymagane żadne zależności. Korzystam tylko z echa i płyty CD wbudowanych w Bash . Jest również dość bezpieczny, ponieważ wszystko jest testowane na każdym etapie i zwraca warunki błędu.
Jeśli nie chcesz podążać za dowiązaniami symbolicznymi, umieść zestaw -P na początku skryptu, ale w przeciwnym razie cd powinien domyślnie rozpoznać dowiązania symboliczne. Został przetestowany z argumentami pliku, które są {absolutne | krewny | dowiązanie symboliczne | local} i zwraca bezwzględną ścieżkę do pliku. Do tej pory nie mieliśmy z tym żadnych problemów.
Możesz to połączyć z innymi funkcjami nazwa_katalogu get, nazwa_pliku get, nazwa_pliku get i nazwa_ścieżki. Można je znaleźć w naszym repozytorium GitHub jako realpath-lib (pełne ujawnienie - to nasz produkt, ale oferujemy go społeczności bez żadnych ograniczeń). Może również służyć jako narzędzie instruktażowe - jest dobrze udokumentowane.
Staraliśmy się jak najlepiej stosować tak zwane „nowoczesne Bash”, ale Bash to duży temat i jestem pewien, że zawsze będzie miejsce na poprawę. Wymaga Bash 4+, ale może być przystosowany do pracy ze starszymi wersjami, jeśli nadal istnieją.
źródło
Ponieważ moja praca jest używana przez osoby z Linuksem innym niż BSD oraz macOS, zdecydowałem się na użycie tych aliasów w naszych skryptach kompilacji (
sed
dołączonych, ponieważ ma podobne problemy):Opcjonalne sprawdzenie, które możesz dodać, aby automatycznie zainstalować zależności homebrew + coreutils :
Przypuszczam, że jest naprawdę „globalny”, musi sprawdzać innych ... ale to prawdopodobnie zbliża się do 80/20.
źródło
Wyjaśnienie
coreutils to
brew
pakiet instalujący podstawowe narzędzia GNU / Linux, które odpowiadają ich implementacji w systemie Mac OSX, dzięki czemu można z nich korzystaćMożesz znaleźć programy lub narzędzia w systemie Mac OSX, które wydają się podobne do coreutils Linuxa („Core Utilities”), ale różnią się pod pewnymi względami (np. Mają różne flagi).
Wynika to z faktu, że implementacja tych narzędzi w systemie Mac OSX jest inna. Aby uzyskać oryginalne zachowanie podobne do GNU / Linux, możesz zainstalować
coreutils
pakiet za pośrednictwembrew
systemu zarządzania pakietami.Spowoduje to zainstalowanie odpowiednich podstawowych narzędzi z prefiksem
g
. Na przykładreadlink
znajdziesz odpowiednigreadlink
program.Aby uzyskać
readlink
wydajność podobną do implementacji GNUreadlink
(greadlink
), możesz utworzyć prosty alias po zainstalowaniu coreutils.Realizacja
Postępuj zgodnie z instrukcjami na https://brew.sh/
brew install coreutils
Możesz umieścić swój alias w ~ / .bashrc, ~ / .bash_profile lub gdziekolwiek jesteś przyzwyczajony do przechowywania aliasów bash. Osobiście trzymam mój w ~ / .bashrc
alias readlink=greadlink
Możesz utworzyć podobne aliasy dla innych coreutils, takich jak gmv, gdu, gdf i tak dalej. Ale uwaga: zachowanie GNU na komputerze Mac może być mylące dla innych osób przyzwyczajonych do pracy z natywnymi rdzeniami lub może zachowywać się w nieoczekiwany sposób w systemie Mac.
źródło
Napisałem narzędzie realpath dla OS X, które może zapewnić takie same wyniki jak
readlink -f
.Oto przykład:
Jeśli używasz MacPorts, możesz zainstalować go za pomocą następującego polecenia:
sudo port selfupdate && sudo port install realpath
.źródło
Naprawdę niezależny od platformy byłby również ten R-onliner
Aby faktycznie naśladować
readlink -f <path>
, należy użyć 2 $ zamiast 1 $.źródło
readlink -f
Implementacja zgodna z POSIX dla skryptów powłoki POSIXhttps://github.com/ko1nksm/readlinkf
Jest to zgodne z POSIX (bez bashizmu). Nie używa
readlink
anirealpath
. Sprawdziłem , że jest dokładnie tak samo, porównując z GNUreadlink -f
(patrz wyniki testu ). Ma obsługę błędów i dobrą wydajność. Możesz bezpiecznie wymienić zreadlink -f
. Licencja jest CC0, więc możesz używać jej do każdego projektu.Proszę odnieść się do najnowszego kodu. Może to naprawić.
źródło
Perl ma funkcję readlink (np. Jak skopiować dowiązania symboliczne w Perlu? ). Działa to na większości platform, w tym OS X:
Na przykład:
źródło
readlink
bez-f
opcji - bez rekurencji, bez ścieżki bezwzględnej - więc równie dobrze możesz użyćreadlink
bezpośrednio.Odpowiedź @Keith Smith daje nieskończoną pętlę.
Oto moja odpowiedź, której używam tylko na SunOS (SunOS tak bardzo brakuje poleceń POSIX i GNU).
Jest to plik skryptu, który musisz umieścić w jednym z katalogów $ PATH:
źródło
Oto, czego używam:
stat -f %N $your_path
źródło
Ścieżki do readlink są różne w moim systemie i twoim. Spróbuj podać pełną ścieżkę:
źródło
readlink
który jest kompatybilny z GNU. Miło to wiedzieć, ale to nie rozwiązuje mojego problemu, ponieważ potrzebuję skryptu, aby działał na maszynie innych ludzi i nie mogę wymagać od nich zainstalowania fink.