Temukan hanya tujuan symlink


50

Untuk digunakan dalam skrip shell, saya mencari cara baris perintah untuk mendapatkan tujuan tautan simbolik. Yang paling dekat saya sejauh ini adalah stat -N src, yang keluaran src -> dst. Tentu saja saya dapat mengurai output dan mendapatkan dst, tetapi saya ingin tahu apakah ada cara langsung untuk mendapatkan tujuan.

Jawaban:


61

Opsi lain adalah menggunakan perintah yang dirancang khusus readlinkjika tersedia.

Misalnya

$ readlink -f `command -v php`
/usr/bin/php7.1

21
Gunakan readlink -fjika Anda ingin mengetahui target symlink terakhir dan tidak hanya yang berikutnya .
— scai

Poin bagus! Lupa itu.
— nikitautiu

11
Perhatikan bahwa itu -fadalah ekstensi non-portabel ke GNU readlink.
— bahamat

2
Kapan tautan baca tidak tersedia? Terima kasih.
— tommy.carstensen

2
@ tommy.carstensen readlink (1) telah ditambahkan ke GNU coreutils pada tahun 2003, jadi hari ini Anda mungkin dapat bergantung padanya pada hampir semua sistem yang menggunakan coreutils. ( Lih. Git.savannah.gnu.org/cgit/coreutils.git/commit/src/… )
— Josip Rodin

16

Di Mac OS X dan FreeBSD / NetBSD / dll. nya:

stat -f %Y <filename>

Secara lebih umum saya kira solusinya adalah (stat --printf =% N menggunakan kutipan aneh):

ls -l b | sed -e 's/.* -> //'

Contoh:

# ln -s a b
# stat -f %Y b
a

Metode lain adalah:

# find b -maxdepth 0 -printf %l
a#

Baris terakhir hancur karena tidak memiliki baris baru, tetapi itu bagus jika Anda membutuhkan hasil dalam variabel, seperti itu

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

The -maxdepthdiperlukan untuk mencegah finddari turun ke direktori jika bterjadi menjadi sebuah direktori.


Saya benar-benar membaca sepintas lalu, stat --printf='%N\n'persis seperti yang saya inginkan, kutipan aneh tidak mengganggu saya, mereka adalah kutipan yang sama rm dan ln
— ThorSummoner

Ini rupanya tidak portabel karena di Linux, stat GNU coreutils '(1) memiliki parameter yang berbeda dan dicetak link -> destdalam output. Solusi find (1) harus diperiksa apakah itu dengan GNU findutils atau lainnya ...
— Josip Rodin

Tolong jangan lupa mengutip ekspansi variabel Anda, echo $ftentu saja tidak menghasilkan apa yang Anda harapkan ketika symlink menunjuk ke /*(ya itu mungkin)
— Camusensei

3

Hal ini dapat dilakukan dengan menggunakan GNU find: find src -prune -printf "%l\n".


1

Portable: tidak beruntung kecuali menggunakan heuristik untuk mem-parsing output ls-l, atau gunakan perl -le 'print readlink("some-file")'

beberapa sistem memiliki readlinkperintah, beberapa dengan -fopsi untuk mendapatkan jalur absolut.

Ada berbagai implementasi statperintah sebagai pembungkus untuk panggilan sistem stat/ lstat. GNU satu tidak berguna dalam hal itu, tetapi zsh's builtin satu lebih dari itu:

zmodload zsh/stat
stat +link the-link

Masih dengan zsh, Anda bisa mendapatkan path absolut dari file (menghapus setiap komponen symlink) dengan :Apengubah (berlaku untuk ekspansi variabel, ekspansi sejarah, dan globbing:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a

1

Pada sistem di mana saya tidak punya readlinkatau statperintah tapi aku punya Python 2.x, saya menggunakan script singkat:

#!/usr/bin/env python

import os, sys

if __name__ == "__main__":
    src = sys.argv[1]
    target = os.readlink(src)
    if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
    print target

Perhatikan bahwa tidak seperti readlink -fini, hanya dapat mengikuti satu tingkat symlink.


1

Portable Bash realpath murni

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}"
}

0

realpathperintah coreutilspaket,

sebagaimana ditautkan dalam readlinkhalaman buku panduan perintah.


sebagai contoh:

realpath /bin/python

output

/usr/bin/python2.7

di mesin saya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.