我使用的是 Ubuntu 20.04,我通常需要找到给定命令的最终可执行路径。我们举awk
个例子:
file $(which awk)
# Output: /usr/bin/awk: symbolic link to /etc/alternatives/awk
file /etc/alternatives/awk
# Output: /etc/alternatives/awk: symbolic link to /usr/bin/gawk
我的问题是:
是否有一个命令(或命令的标志file
)将直接返回给定命令的最终路径?在上面的例子中我希望它返回的路径gawk
谢谢
答案1
您可以使用readlink
:
$ readlink -f -- "$(which awk)"
/usr/bin/gawk
从man readlink
:
-f, --规范化 通过递归地跟踪给定名称的每个组件中的每个符号链接来规范化;除最后一个组件外的所有组件都必须存在
答案2
我发现了另一个命令realpath
:
realpath -- "$(which awk)"
#Output: /usr/bin/gawk
答案3
如果您想告诉file
Linux 上的命令返回有关该awk
命令的信息,并在执行此操作时解析所有符号链接,请file
与其-L
选项一起使用:
$ file -L -- "$(command -v awk)"
/bin/awk: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b863ebf57d3cc33d8e7fed3be0e0b5d235489b46, for GNU/Linux 3.2.0, stripped
要解析所有链接以获取命令的最终绝对路径,请使用readlink -e
:
$ readlink -e -- "$(command -v awk)"
/usr/bin/gawk
答案4
在 中zsh
,如果变量 中有一个命令名称$cmd
,$cmd:c
将扩展到命令的路径(通过查找$PATH
/ $path
),并且:P
可以使用限定符来获取相应的真实路径(使用标准 C 函数时,文件的无符号链接规范绝对路径realpath()
):
$ cmd=awk
$ print -r -- $cmd:c
/usr/bin/awk
$ print -r -- $cmd:c:P
/usr/bin/gawk
$ file -- $cmd:c:P
/usr/bin/gawk: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b863ebf57d3cc33d8e7fed3be0e0b5d235489b46, for GNU/Linux 3.2.0, stripped
$ namei -l -- $cmd:c
f: /usr/bin/awk
drwxr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root bin
lrwxrwxrwx root root awk -> /etc/alternatives/awk
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root alternatives
lrwxrwxrwx root root awk -> /usr/bin/gawk
drwxr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root bin
-rwxr-xr-x root root gawk
为了避免中间变量,可以使用匿名函数:
$ (){print -r -- $1:c:P} awk
/usr/bin/gawk
或者一个普通的函数:
$ canonical-path-of() print -rC1 -- $@:c:P
$ canonical-path-of awk ls
/usr/bin/gawk
/usr/bin/ls
您还可以使用=cmd
运算符,它是以下形式文件名扩展喜欢波形符扩展但它扩展到相应命令的路径,并且:P
此时仍然应用修饰符作为全局限定符²:
$ print -r -- =awk
/usr/bin/awk
$ print -r -- =awk(:P)
/usr/bin/gawk
$ print -r -- =blah
zsh: blah not found
但请注意,如果在 中 找不到该命令$PATH
,$cmd:c
将扩展为与 相同的内容$cmd
,并将扩展为相对于当前工作目录$cmd:c:P
的路径。$cmd
² 这次当找不到命令时,就会触发致命错误。=cmd
可以通过以下方式禁用该扩展set +o equals