如何使用file命令找到最终的可执行文件路径?

Ama*_*_05 5 linux symlink

我使用的是 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
Run Code Online (Sandbox Code Playgroud)

我的问题是:

是否有一个命令(或命令的标志file)将直接返回给定命令的最终路径?在上面的例子中我希望它返回的路径gawk

谢谢

sch*_*ity 10

您可以使用readlink

$ readlink -f -- "$(which awk)"
/usr/bin/gawk
Run Code Online (Sandbox Code Playgroud)

man readlink

-f, --canonicalize 通过递归地跟踪给定名称的每个组件中的每个符号链接来规范化;除最后一个组件外的所有组件都必须存在


Ama*_*_05 8

我发现了另一个命令realpath

realpath -- "$(which awk)"
#Output: /usr/bin/gawk

Run Code Online (Sandbox Code Playgroud)


Sté*_*las 5

在 中zsh,如果变量中有命令名称$cmd$cmd:c将扩展到命令\xc2\xb9 的路径(通过查找$PATH/ $path),并且:P限定符可用于获取相应的实际路径(无符号链接)使用标准 C 函数时文件的规范绝对路径realpath()):

\n
$ cmd=awk\n$ print -r -- $cmd:c\n/usr/bin/awk\n$ print -r -- $cmd:c:P\n/usr/bin/gawk\n$ file -- $cmd:c:P\n/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\n$ namei -l -- $cmd:c\nf: /usr/bin/awk\ndrwxr-xr-x root root /\ndrwxr-xr-x root root usr\ndrwxr-xr-x root root bin\nlrwxrwxrwx root root awk -> /etc/alternatives/awk\ndrwxr-xr-x root root   /\ndrwxr-xr-x root root   etc\ndrwxr-xr-x root root   alternatives\nlrwxrwxrwx root root   awk -> /usr/bin/gawk\ndrwxr-xr-x root root     /\ndrwxr-xr-x root root     usr\ndrwxr-xr-x root root     bin\n-rwxr-xr-x root root     gawk\n
Run Code Online (Sandbox Code Playgroud)\n

为了避免中间变量,可以使用匿名函数:

\n
$ (){print -r -- $1:c:P} awk\n/usr/bin/gawk\n
Run Code Online (Sandbox Code Playgroud)\n

或者一个普通的函数:

\n
$ canonical-path-of() print -rC1 -- $@:c:P\n$ canonical-path-of awk ls\n/usr/bin/gawk\n/usr/bin/ls\n
Run Code Online (Sandbox Code Playgroud)\n
\n

您还可以使用=cmd运算符,它是文件名扩展的一种形式,例如波浪号扩展,但扩展为相应命令的路径,并且:P此时仍然将修饰符应用为glob 限定符\xc2\xb2:

\n
$ print -r -- =awk\n/usr/bin/awk\n$ print -r -- =awk(:P)\n/usr/bin/gawk\n$ print -r -- =blah\nzsh: blah not found\n
Run Code Online (Sandbox Code Playgroud)\n
\n

\xc2\xb9 但请注意,如果在 , 中找不到该命令$PATH$cmd:c将扩展为与 , 相同的内容$cmd,并将扩展为相对于当前工作目录$cmd:c:P的路径。$cmd

\n

\xc2\xb2 这次当找不到命令时,会触发致命错误。=cmd可以通过以下方式禁用该扩展set +o equals

\n


Kus*_*nda 5

如果您想告诉fileLinux 上的命令返回有关该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
Run Code Online (Sandbox Code Playgroud)

要解析所有链接以获取命令的最终绝对路径,请使用readlink -e

$ readlink -e -- "$(command -v awk)"
/usr/bin/gawk
Run Code Online (Sandbox Code Playgroud)