Дізнайтеся символічну ціль посилання за допомогою командного рядка


129

Скажіть, що я встановлюю символічне посилання:

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

чи є спосіб побачити, яку ціль myothertextfile.txtвикористовує командний рядок?

Відповіді:


170

Використовуйте -fпрапор для друку канонізованої версії. Наприклад:

readlink -f /root/Public/myothertextfile.txt

Від man readlink:

-f, --canonicalize
      canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist

8
Як запропоновано в іншому запитанні , ви можете використовувати readlink -f.
Denilson Sá Maia

5
Для того, щоб отримати цю роботу на Mac OS X, brew install coreutils. При цьому встановлюються основні версії gnu з командами з префіксом g, тобтоgreadlink -f somefile
Mike D

з перемикачем -f, команда нічого не повертає в моєму випадку ..
sotn

Використання -f дало мені інформацію, яку я хотів, тобто вирішити декілька символьних посилань та показати кінцеву ціль.
isapir

на Ubuntu 18.04.1 LTS (Bionic Beaver)манежах readlink є примітка, що говорить "Примітка realpath (1) є кращою командою, яка використовується для функціонування канонізації."
Сам Каменський

23

readlink - команда, яку ви хочете. Для команди слід переглянути сторінку чоловіка. Тому що якщо ви хочете перейти до ланцюжка символічних посилань на фактичний файл, то вам потрібен перемикач -e або -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

З першою відповіддю нічого поганого, але ця є більш повною і корисною.
Майк S

6

Це також буде працювати:

ls -l /root/Public/myothertextfile.txt

але readlinkбуде кращим для використання в сценарії, а не для розбору ls.


4

Якщо ви хочете показати джерело та призначення посилання, спробуйте stat -c%N files*. Напр

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

Це не добре для розбору (використання readlinkдля цього), але воно показує ім'я посилання та призначення, без захаращенняls -l

-cможе бути записаний --formatі %Nозначає "ім'я файлу з цитатами з відхиленням, якщо символічне посилання".


2

Це readlinkхороша річ, але GNU-специфічна і непересічна платформа. Я писав крос-платформні сценарії для /bin/sh, тому я використовував щось на кшталт:

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

або:

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

але це потрібно перевірити на різних платформах. Я думаю, вони працюватимуть, але не впевнені на 100% у lsформаті виводу.

Результат lsтакож може бути проаналізований в межах, bashне залежно від зовнішньої команди типу awk, sedабо perl.

Ця bash_realpathфункція вирішує кінцеве призначення посилання (посилання → посилання → посилання → остаточне):

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

1

Якщо ви не можете скористатися readlink, то аналіз результату ls -lможна зробити так.

Нормальним результатом буде:

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

Тому ми хочемо замінити все перед "->" і стрілкою, що входить. Ми могли б використати sedдля цього:

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

1

Питання недостатньо точне, щоб дати просту відповідь, як відповідь Брайан-Бразилії:

readlink -f some_path

дійсно буде відмежувати кожне символьне посилання, що бере участь у побудові шляху до кінцевої цілі позаду some_path.

Але один рівень каскадних посилань - це лише окремий випадок серед інших систем, загальним випадком є ​​N рівнів каскадних символьних посилань. Подивіться на наступне в моїй системі:

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

rwhich- це моя власна рекурсивна реалізація, whichяка друкує всі проміжні каскадні символьні посилання (на stderr) до кінцевої цілі (до stdout).

Тоді, якщо я хочу знати, що таке:

  • ціль symlink / usr / bin / emacs **, очевидна відповідь мені /etc/alternatives/emacsяк повертається:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • остаточна мета за каскадних симлінк / USR / BIN / Emacs, відповідь має бути /usr/bin/emacs24-xяк повернута:

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

0

llабо ls -lслід перелічити елементи каталогу, включаючи ваше символічне посилання та його ціль

cd -P /root/Public/myothertextfile.txt (у вашому випадку) має вказувати на початковий шлях


0

Якщо ви знайдете ціль усіх посилань у папці та її підпапці, використовуйте find . -type l -lsкоманду з типом посилання таким чином:

me@local.localdomain:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Якщо ви хочете націлити на одиницю, тоді ls -lслід попрацювати:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.