Ответы:
Используйте -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
.