Znajdź symboliczny cel łącza za pomocą wiersza poleceń

129

Powiedz, że skonfigurowałem dowiązanie symboliczne:

ln -s /root/Public/mytextfile.txt /root/Public/myothertextfile.txt

czy jest sposób, aby zobaczyć, do czego cel myothertextfile.txtużywa linii poleceń?

Jared
źródło

Odpowiedzi:

170

Użyj -fflagi, 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
brian-brazil
źródło
8
Jak sugerowano w innym pytaniu , możesz chcieć użyć readlink -f.
Denilson Sá Maia
5
Aby uzyskać tej pracy w systemie Mac OS X brew install coreutils. To instaluje podstawowe wersje GNU poleceń poprzedzonych literą g, tj.greadlink -f somefile
Mike D
z przełącznikiem -f, polecenie zwraca nic w moim przypadku ..
sotn
Użycie -f dało mi informacje, których potrzebowałem, tj. Rozwiązywanie wielu dowiązań symbolicznych i pokazywanie celu końcowego.
isapir
na Ubuntu 18.04.1 LTS (Bionic Beaver)stronach readlink znajduje się informacja „Uwaga realpath (1) jest preferowanym poleceniem używanym do funkcji kanonizacji”.
Sam Kamensky
23

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
Kyle Brandt
źródło
Pierwsza odpowiedź nie jest niczym złym, ale ta jest bardziej kompletna i pomocna.
Mike S
6

Będzie to również działać:

ls -l /root/Public/myothertextfile.txt

ale readlinkbyłby preferowany do użycia w skrypcie zamiast analizy ls.

Dennis Williamson
źródło
4

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 readlinkdo tego), ale pokazuje nazwę i miejsce docelowe linku, bez bałaganuls -l

-cmożna zapisać --formati %Noznacza „cytowaną nazwę pliku z dereferencją w przypadku dowiązania symbolicznego”.

Robert Siemer
źródło
2

To readlinkdobra 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 lsformatu wyjściowego.

Wynikiem lsmoże być również przetwarzane w ciągu bashbez konieczności polegania na zewnętrznym poleceniem awk, sedlub perl.

Ta bash_realpathfunkcja 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}"
}
Роман Коптев
źródło
1

Jeśli nie możesz użyć readlink, wówczas parsowanie wyniku ls -lmoż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ę seddo tego:

ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
7ochem
źródło
1

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

rwhichjest moją własną rekurencyjną implementacją, whichktó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-xzwrócony przez:

    readlink -f $(which emacs)
    readlink -f /usr/bin/emacs
    rwhich emacs 2>/dev/null
    
Nico
źródło
0

lllub ls -lpowinien wyświetlić listę elementów katalogu, w tym symboliczny link i jego cel

cd -P /root/Public/myothertextfile.txt (w twoim przypadku) powinien wskazywać na oryginalną ścieżkę

Mantz
źródło
0

Jeśli znajdziesz cel wszystkich łączy w folderze i jego podfolderze, użyj find . -type l -lspolecenia z typem łącza w następujący sposób:

[email protected]:~/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 -lpowinien działać:

[email protected]:~/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
Memin
źródło