如何查看符号链接的完整绝对路径

215

当我使用ls -la symlinkName或者stat symlinkName命令时,并不会展示出完整的路径(例如:../../../one/two/file.txt)。

在Linux中,有什么命令能够显示出完整的路径呢?


5
在这里需要小心:当ls或stat显示没有绝对路径时 - 这个链接没有绝对路径!这在设备被挂载在不同的上下文中时尤为重要(例如,如果您将某些内容放在CD或USB闪存驱动器上,或者尝试恢复一些损坏的硬盘驱动器)。所有提到的解决方案(realpath、readlink等)仅在挂载的上下文中显示绝对路径。 - flolo
readlink symlinkName 不带 -f 选项会显示相对路径,如果符号链接是使用相对路径定义的。 - midnite
10个回答

343

realpath 不是所有 Linux 发行版都可用,但 readlink 应该可以。

readlink -f symlinkName

上面的代码应该能解决问题。

或者,如果你没有安装上述插件中的任何一个,但有安装 Python 2.6(或更高版本),你可以执行以下操作:

python -c 'import os.path; print(os.path.realpath("symlinkName"))'

26
如果使用OSX,则省略-f标志,然后就可以正常工作。即:readlink symlinkName - Josh Davenport-Smith
11
在OSX上省略-f标志只会得到一个相对路径。 - timoxley
5
这个问题是关于Linux的,大家。 - Ian Stapleton Cordasco
1
在Ubuntu上,我不需要使用-f标志。 - satnam
1
在我的 OSX 上有效。 - Nic Wanavit

47

realpath <符号链接文件的路径>应该能解决问题。


2
“man realpath” 显示在底部,它是“GNU coreutils”的一部分。我非常确定“GNU coreutils”通常会随着Ubuntu一起提供,所以即使 @IanStapletonCordasco 说“realpath 并不适用于所有 Linux 发行版”,但我认为它至少应该在所有 Ubuntu 和 Ubuntu 派生版本中提供。 - Gabriel Staples

13

Unix系统 -> ll symLinkName

OSX系统 -> readlink symLinkName

区别在于第一种方式会以闪烁的方式显示符号链接路径,而第二种方式只会在控制台上回显出它。


1
这个问题特别要求提供完整/绝对路径,而不是相对路径(../../file.txt)。这两个答案都会给出相对路径。 - wisbucky

7

我将在此处进行简短的评论和分析,但对于那些TL;DR,这里有一个bash的单行代码,有助于锚定工作目录:

script_home=$( dirname $(realpath "$0") )

您也可以使用任何其他文件名来替代$0以确定其真实位置。

不仅有某些文件的真实路径需要确定的问题,而且特别是一些脚本通过符号链接从另一个位置调用并需要相对于其真正的工作目录引用其他资源。

详情如下。 假设我们有真实的脚本或文件和指向它的符号链接:

$ ls -la
-rwxr-xr-x 1 root    root  0 Mar 20 07:05 realscript.sh
lrwxrwxrwx 1 root    root 10 Mar 20 07:05 symlink -> realscript.sh

GNU coreutils 中有一些非常有用的命令:

$ realpath symlink
/home/test/realscript.sh

请参阅原始文件:

realpath realscript.sh
/home/test/realscript.sh

在脚本中,非常好的组合方式是使用 dirname

$ dirname /home/test/realscript.sh
/home/test

总之,您可以在脚本中使用它

echo  $( dirname $(realpath "symlink") )

或者获取并存储在变量中实际的脚本主目录,并保存代码以获取实际路径脚本 realscript.sh:

script_home=$( dirname $(realpath "$0") )
echo Original script home: $script_home

在Shell脚本中,"$0"被定义为"self"。

为了测试一切是否正常,我们将符号链接放入/home/test2/中,修改一些其他的内容,然后从根目录运行/调用它:

$ /home/test2/symlink
/home/test
Original script home: /home/test
Original script is: /home/test/realscript.sh
Called script is: /home/test2/symlink

2021年更新,还有一个命令:

readlink - 打印已解析的符号链接或规范文件名

说明 请注意,realpath(1) 是首选用于规范化功能的命令。

请尝试自行编写修改后的输出:)


5

您可以使用 awk 命令结合 system 调用 readlink 来获取带有完整符号链接路径的 ls 输出的等效结果。例如:

ls | awk '{printf("%s ->", $1); system("readlink -f " $1)}'

将显示例如

thin_repair ->/home/user/workspace/boot/usr/bin/pdata_tools
thin_restore ->/home/user/workspace/boot/usr/bin/pdata_tools
thin_rmap ->/home/user/workspace/boot/usr/bin/pdata_tools
thin_trim ->/home/user/workspace/boot/usr/bin/pdata_tools
touch ->/home/user/workspace/boot/usr/bin/busybox
true ->/home/user/workspace/boot/usr/bin/busybox

ls可以不用readlink来实现;只需使用ls -l。但这种方法根本行不通,它会尝试对目录中的所有非链接文件进行操作,并且如果你的ls配置使用颜色,awk将完全失效。只需使用find . -maxdepth 1 -type l -ls | awk '{print $11 "\t" $12 "\t" $13}' - Hashbrown

5
另一种查看信息的方法是使用stat命令,它可以显示更多信息。在我的机器上运行命令stat ~/.ssh会显示:
File: ‘/home/sumon/.ssh’ -> ‘/home/sumon/ssh-keys/.ssh.personal’
  Size: 34          Blocks: 0          IO Block: 4096   symbolic link
Device: 801h/2049d  Inode: 25297409    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/   sumon)   Gid: ( 1000/   sumon)
Access: 2017-09-26 16:41:18.985423932 +0600
Modify: 2017-09-25 15:48:07.880104043 +0600
Change: 2017-09-25 15:48:07.880104043 +0600
 Birth: -

希望能对某些人有所帮助。

3
在macOS Catalina中尝试 -
readlink -n `which <command>`

示例输入 -

readlink -n `which adb`

示例输出 -

/usr/local/Caskroom/android-platform-tools/31.0.1,d027ce0f9f214a4bd575a73786b44d8ccf7e7516/platform-tools/adb

0

在我的Mac上,我有以下内容:

例如创建到目录的符号链接:ln -s /Users/test/play/game game

然后,如果我使用符号链接进入目录:cd game,如果我输入命令:pwd,则实际目录为:~

如果我决定出于某种原因实际更改到目录:/Users/test/play/game,我在我的.bash_profile中设置了一个别名:

alias cdp='cd -P $(basename `pwd`)'

在使用上述cdp别名后,跟随pwd命令,当前目录为:/Users/test/play/game


0

Mac > 终端 中获取符号链接实际指向路径的方法:

ls -lrt <Symlink path/symlink>

0

find -maxdepth 1 -type l -printf "%l\n"

查找 -maxdepth 1 -类型 l -打印 "%l\n"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接