Odpowiedzi:
Użyj -f
flagi, aby wydrukować wersję kanoniczną. Na przykład:
readlink -f /root/Public/myothertextfile.txt
Od man readlink
:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
brew install coreutils
. To instaluje podstawowe wersje GNU poleceń poprzedzonych literą g
, tj.greadlink -f somefile
Ubuntu 18.04.1 LTS (Bionic Beaver)
stronach readlink znajduje się informacja „Uwaga realpath (1) jest preferowanym poleceniem używanym do funkcji kanonizacji”.
readlink to polecenie, które chcesz. Powinieneś spojrzeć na stronę podręcznika dla polecenia. Ponieważ jeśli chcesz śledzić łańcuch dowiązań symbolicznych do rzeczywistego pliku, potrzebujesz przełącznika -e lub -f:
$ ln -s foooooo zipzip # fooooo doesn't actually exist
$ ln -s zipzip zapzap
$ # Follows it, but doesn't let you know the file doesn't actually exist
$ readlink -f zapzap
/home/kbrandt/scrap/foooooo
$ # Follows it, but file not there
$ readlink -e zapzap
$ # Follows it, but just to the next symlink
$ readlink zapzap
zipzip
Będzie to również działać:
ls -l /root/Public/myothertextfile.txt
ale readlink
byłby preferowany do użycia w skrypcie zamiast analizy ls
.
Jeśli chcesz pokazać źródło i miejsce docelowe linku, spróbuj stat -c%N files*
. Na przykład
$ stat -c%N /dev/fd/*
‘/dev/fd/0’ -> ‘/dev/pts/4’
‘/dev/fd/1’ -> ‘/dev/pts/4’
Nie nadaje się do parsowania (użyj readlink
do tego), ale pokazuje nazwę i miejsce docelowe linku, bez bałaganuls -l
-c
można zapisać --format
i %N
oznacza „cytowaną nazwę pliku z dereferencją w przypadku dowiązania symbolicznego”.
To readlink
dobra rzecz, ale specyficzna dla GNU i nieprzenikająca między platformami. Kiedyś pisałem skrypty dla wielu platform /bin/sh
, dlatego używałbym czegoś takiego:
ls -l /root/Public/myothertextfile.txt | awk '{print $NF}'
lub:
ls -l /root/Public/myothertextfile.txt | awk -F"-> " '{print $2}'
ale należy je przetestować na różnych platformach. Myślę, że będą działać, ale nie są w 100% pewni ls
formatu wyjściowego.
Wynikiem ls
może być również przetwarzane w ciągu bash
bez konieczności polegania na zewnętrznym poleceniem awk
, sed
lub perl
.
Ta bash_realpath
funkcja rozwiązuje ostateczne miejsce docelowe łącza (link → link → link → final):
bash_realpath() {
# print the resolved path
# @params
# 1: the path to resolve
# @return
# >&1: the resolved link path
local path="${1}"
while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
do
path="${BASH_REMATCH[1]}"
done
echo "${path}"
}
Jeśli nie możesz użyć readlink
, wówczas parsowanie wyniku ls -l
może być wykonane w ten sposób.
Normalny wynik to:
ls -l /root/Public/myothertextfile.txt
lrwxrwxrwx 1 root root 30 Jan 1 12:00 /root/Public/myothertextfile.txt -> /root/Public/mytextfile.txt
Chcemy więc zamienić wszystko przed „->” i dołączoną strzałką. Przydałoby się sed
do tego:
ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
Pytanie nie jest wystarczająco dokładne, aby dać prostą odpowiedź na pytanie brian-brazil:
readlink -f some_path
faktycznie odrzuci każde dowiązanie symboliczne zaangażowane w konstrukcję ścieżki do końcowego celu z tyłu some_path
.
Ale jeden poziom kaskadowych dowiązań symbolicznych jest tylko szczególnym przypadkiem między innymi w systemie, przy czym ogólny przypadek to N poziomów kaskadowych dowiązań symbolicznych. Spójrz na następujące elementy w moim systemie:
$ rwhich emacs
/usr/bin/emacs
/etc/alternatives/emacs
/usr/bin/emacs24-x
rwhich
jest moją własną rekurencyjną implementacją, which
która drukuje wszystkie pośrednie kaskadowe dowiązania symboliczne (do stderr) aż do ostatecznego celu (do stdout).
Jeśli chcę wiedzieć, co to jest:
cel dowiązania symbolicznego / usr / bin / emacs **, oczywista odpowiedź brzmi /etc/alternatives/emacs
:
readlink $(which emacs)
readlink /usr/bin/emacs
ostateczny cel za kaskadowe dowiązania symboliczne / usr / bin / emacs, odpowiedź musi być /usr/bin/emacs24-x
zwrócony przez:
readlink -f $(which emacs)
readlink -f /usr/bin/emacs
rwhich emacs 2>/dev/null
Jeśli znajdziesz cel wszystkich łączy w folderze i jego podfolderze, użyj find . -type l -ls
polecenia z typem łącza w następujący sposób:
me@local.localdomain:~/test$ find . -type l -ls
8601855888 0 lrwxr-xr-x 1 me staff 6 Jan 24 19:53 ./link -> target
Jeśli chcesz cel pojedynczego, ls -l
powinien działać:
me@local.localdomain:~/test$ ls -l
total 0
lrwxr-xr-x 1 me staff 6 Jan 24 19:53 link -> target
-rw-r--r-- 1 me staff 0 Jan 24 19:53 target
readlink -f
.