シェルスクリプトで使用するために、シンボリックリンクの宛先を取得するコマンドライン方法を探しています。これまでのところ最も近いのはstat -N src
で、これはsrc -> dst
を出力します。もちろん、出力を解析してdst
を取得することもできますが、宛先を取得する直接的な方法があるのだろうかと思います。
別のオプションは、特別に設計されたコマンドreadlink
を使用することです(可能な場合)。
例えば。
$ readlink -f `command -v php`
/usr/bin/php7.1
Mac OS XおよびFreeBSD/NetBSD/etc。それは:
stat -f %Y <filename>
より一般的に私は解決策だと思います(stat --printf =%Nは奇妙な引用を使用します):
ls -l b | sed -e 's/.* -> //'
例:
# ln -s a b
# stat -f %Y b
a
別の方法は次のとおりです。
# find b -maxdepth 0 -printf %l
a#
最後の行には改行がないためマングルされていますが、変数で結果を必要とする場合などは問題ありません。
# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a
-maxdepth
は、find
がディレクトリである場合にb
がディレクトリに降りないようにするために必要です。
GNU find
:find src -Prune -printf "%l\n"
。
ポータブルピュアバッシュリアルパス
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}"
}
移植性:ヒューリスティックを使用してls -l出力を解析するか、Perl -le 'print readlink("some-file")'
を使用する以外は運がない
一部のシステムにはreadlink
コマンドがあり、絶対パスを取得するために-f
オプションが付いているシステムもあります。
stat
/stat
システムコールのラッパーとしてのlstat
コマンドのさまざまな実装があります。 GNU oneはその点では役に立ちませんが、zshの組み込みの方がより便利です。
zmodload zsh/stat
stat +link the-link
それでもzshを使用すると、:A
修飾子を使用して、ファイルの絶対パスを取得できます(すべてのsymlinkコンポーネントを削除します)(変数の展開、履歴の展開、およびグロビングに適用されます)。
~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a
readlink
コマンドもstat
コマンドもないシステムでPython 2.xは持っていますが、短いスクリプトを使用しています:
#!/usr/bin/env python
import os, sys
if __name__ == "__main__":
src = sys.argv[1]
target = os.readlink(src)
if not os.path.isabs(target):
target = os.path.abspath(os.path.join(os.path.dirname(src), target))
print target
readlink -f
とは異なり、これは1レベルのシンボリックリンクのみに従う場合があることに注意してください。
realpath
パッケージのcoreutils
コマンド、
readlink
コマンドのマニュアルページにリンクされています。
例えば:
realpath /bin/python
出力
/usr/bin/python2.7
私のマシンで。