Відповіді:
Використовуйте -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
brew install coreutils
. При цьому встановлюються основні версії gnu з командами з префіксом g
, тобтоgreadlink -f somefile
Ubuntu 18.04.1 LTS (Bionic Beaver)
манежах readlink є примітка, що говорить "Примітка realpath (1) є кращою командою, яка використовується для функціонування канонізації."
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
Це також буде працювати:
ls -l /root/Public/myothertextfile.txt
але readlink
буде кращим для використання в сценарії, а не для розбору ls
.
Якщо ви хочете показати джерело та призначення посилання, спробуйте 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
означає "ім'я файлу з цитатами з відхиленням, якщо символічне посилання".
Це 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}"
}
Якщо ви не можете скористатися 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
Питання недостатньо точне, щоб дати просту відповідь, як відповідь Брайан-Бразилії:
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
Якщо ви знайдете ціль усіх посилань у папці та її підпапці, використовуйте 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
readlink -f
.