Cari tahu target tautan simbolis melalui baris perintah

130

Katakanlah saya menyiapkan tautan simbolis:

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

apakah ada cara untuk melihat apa target myothertextfile.txtmenggunakan baris perintah?

Jared
sumber

Jawaban:

171

Gunakan -fbendera untuk mencetak versi kanonik. Sebagai contoh:

readlink -f /root/Public/myothertextfile.txt

Dari 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
sumber
8
Seperti yang disarankan dalam pertanyaan lain , Anda mungkin ingin menggunakannya readlink -f.
Denilson Sá Maia
5
Untuk mengaktifkan ini di Mac OS X brew install coreutils,. Ini menginstal versi gnu dasar dari perintah yang diawali dengan huruf g, yaitugreadlink -f somefile
Mike D
dengan -f switch, perintah tidak mengembalikan apa pun dalam kasus saya ..
sotn
Menggunakan -f memberi saya informasi yang saya inginkan, yaitu menyelesaikan beberapa symlink dan menunjukkan target akhir.
isapir
pada Ubuntu 18.04.1 LTS (Bionic Beaver)halaman readlink ada catatan yang mengatakan "Note realpath (1) adalah perintah yang disukai untuk digunakan untuk fungsionalitas kanonikisasi."
Sam Kamensky
23

readlink adalah perintah yang Anda inginkan. Anda harus melihat halaman manual untuk perintah. Karena jika Anda ingin mengikuti rantai tautan simbolik ke file aktual, maka Anda memerlukan sakelar -e atau -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
sumber
Tidak ada yang salah dengan jawaban pertama, tetapi yang ini lebih lengkap dan bermanfaat.
Mike S
6

Ini juga akan berfungsi:

ls -l /root/Public/myothertextfile.txt

tetapi readlinkakan lebih disukai untuk digunakan dalam skrip daripada parsing ls.

Dennis Williamson
sumber
4

Jika Anda ingin menunjukkan sumber dan tujuan tautan, coba stat -c%N files*. Misalnya

$ stat -c%N /dev/fd/*
‘/dev/fd/0’ -> ‘/dev/pts/4’
‘/dev/fd/1’ -> ‘/dev/pts/4’

Ini tidak baik untuk parsing (gunakan readlinkuntuk itu), tetapi itu menunjukkan nama tautan dan tujuan, tanpa kekacauanls -l

-cdapat ditulis --formatdan %Nberarti "nama file yang dikutip dengan dereferensi jika tautan simbolik".

Robert Siemer
sumber
2

Ini readlinkadalah hal yang baik, tetapi platform khusus GNU dan non lintas. Saya biasa menulis skrip lintas platform /bin/sh, oleh karena itu saya akan menggunakan sesuatu seperti:

 ls -l /root/Public/myothertextfile.txt | awk '{print $NF}'

atau:

 ls -l /root/Public/myothertextfile.txt | awk -F"-> " '{print $2}'

tetapi ini perlu diuji pada platform yang berbeda. Saya pikir mereka akan bekerja, tetapi tidak 100% yakin untuk lsformat output.

Hasil dari lsjuga dapat diuraikan di dalam bashtanpa tergantung pada perintah eksternal seperti awk, sedatau perl.

bash_realpathFungsi ini , menyelesaikan tujuan akhir suatu tautan (tautan → tautan → tautan → 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}"
}
Роман Коптев
sumber
1

Jika Anda tidak dapat menggunakan readlink, maka penguraian hasil ls -ldapat dilakukan seperti ini.

Hasil normal adalah:

ls -l /root/Public/myothertextfile.txt
lrwxrwxrwx 1 root root 30 Jan  1 12:00 /root/Public/myothertextfile.txt -> /root/Public/mytextfile.txt

Jadi kami ingin mengganti semuanya sebelum "->" dan panah disertakan. Kita bisa menggunakan sedini:

ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
7ochem
sumber
1

Pertanyaannya tidak cukup akurat untuk memberikan jawaban sederhana seperti brian-brazil:

readlink -f some_path

memang akan melakukan dereferensi setiap symlink yang terlibat dalam path membangun ke target akhir di belakang some_path.

Tetapi satu level dari symlink cascading hanyalah sebuah kasus khusus di antara yang lain dalam suatu sistem, kasus yang umum adalah level N dari symlink cascading. Lihatlah yang berikut di sistem saya:

$ rwhich emacs
/usr/bin/emacs
 /etc/alternatives/emacs
  /usr/bin/emacs24-x

rwhichadalah implementasi rekursif saya sendiri whichyang mencetak semua symlink cascading menengah (ke stderr) ke target akhir (ke stdout).

Maka jika saya ingin tahu apa itu:

  • target symlink / usr / bin / emacs **, jawaban yang jelas bagi saya adalah /etc/alternatives/emacsdikembalikan oleh:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • yang akhir sasaran belakang Cascading symlink / usr / bin / emacs, jawabannya akan /usr/bin/emacs24-xseperti dikembalikan oleh:

    readlink -f $(which emacs)
    readlink -f /usr/bin/emacs
    rwhich emacs 2>/dev/null
    
Nico
sumber
0

llatau ls -lharus mendaftar item direktori, termasuk tautan simbolis Anda dan targetnya

cd -P /root/Public/myothertextfile.txt (dalam kasus Anda) harus mengarah ke jalur asli

Mantz
sumber
0

Jika Anda menemukan target semua tautan di dalam folder dan subfoldernya gunakan find . -type l -lsperintah dengan tipe tautan sebagai berikut:

[email protected]:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Jika Anda ingin target satu, maka ls -lharus berfungsi:

[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
sumber