fileコマンドを使用して最終的な実行可能ファイルパスを見つけるには?

fileコマンドを使用して最終的な実行可能ファイルパスを見つけるには?

私は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

Linuxでコマンドに関する情報をfile返し、それを行うときにすべてのシンボリックリンクを確認するようにコマンドするには、次のオプションと一緒に使用します。awkfile-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

関連情報