Узнайте символическую цель ссылки через командную строку

130

Скажите, что я установил символическую ссылку:

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

Есть ли способ увидеть, что цель myothertextfile.txtиспользует командную строку?

Джаред
источник

Ответы:

171

Используйте -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.
Денилсон Са Майя
5
Для того, чтобы получить эту работу на Mac OS X, brew install coreutils. При этом устанавливаются базовые версии команд GNU с префиксом буквы g, т. Е.greadlink -f somefile
Майк Д
с ключом -f команда ничего не возвращает в моем случае ..
Sotn
Использование -f дало мне информацию, которую я хотел, то есть разрешил несколько символических ссылок и показал конечную цель.
Исапир
на 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
Кайл Брандт
источник
Ничего плохого в первом ответе, но этот является более полным и полезным.
Майк С.
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
7ochem
источник
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 (в вашем случае) должен указывать на исходный путь

Mantz
источник
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
Memin
источник