通过命令行找出符号链接目标


129

假设我设置了一个符号链接:

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

有没有办法查看myothertextfile.txt使用命令行的目标?

Answers:


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
DenilsonSáMaia 2014年

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的联机帮助页上有一条注释,上面写着“ Note realpath(1)是用于规范化功能的首选命令”。
Sam Kamensky

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

第一个答案没有错,但是这个答案更完整,更有用。
Mike S


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,而不依赖于外部命令等awksedperl

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

llls -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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.