シンボリックリンクを含むことができる相対パスから絶対(および正規化された)パスを取得するUnixコマンドはありますか?
答え1
あなたはそれを使用することができますreadlink
ユーティリティ(-f
オプションを含む):
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
次のようないくつかのディストリビューションGNUコアツールそしてFreeBSDrealpath(1)
、デフォルトでは呼び出しのみを実行するユーティリティも付属しています。realpath(3)
そしてほぼ同じことをします。
答え2
ポータブルで、PWD
変えるシェルによって現在のディレクトリの絶対位置に設定されます。このパスのすべてのコンポーネントはシンボリックリンクになります。
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
.
とを削除するには、..
ファイルを含むディレクトリに変更して$PWD
そのディレクトリにインポートします。
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
シンボリックリンクを追跡する移植可能な方法はありません。ディレクトリパスがある場合、ほとんどの unices は$(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
シンボリックリンクを使用せずにパスを提供します。シンボリックリンクに従うシェルはそうする傾向があるからですpwd -P
(「P」は「物理的」を表す)。
一部のユニスは、ファイルの「物理的」パスを印刷するユーティリティを提供します。
- 最新のLinuxシステム(GNU coreutilsまたはBusyBoxを含む)では
readlink -f
、FreeBSD ≥8.3、NetBSD ≥4.0、OpenBSD 2.2 の場合も同様です。 - FreeBSD ≥4.3 例
realpath
(一部のLinuxシステムにも存在し、BusyBoxにあります)。 Perlが利用可能な場合は、次のものを使用できます。
Cwd
基準寸法。perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
答え3
pwd
あなたのニーズに適していますか?現在のディレクトリの絶対パスを提供します。またはあなたが望むものはおそらく実際のパス()。
答え4
ここの他の答えは良いですが、私の要件には十分ではありません。すべてのコンピュータのスクリプトで利用可能なソリューションが必要です。私の解決策は、必要なスクリプトから呼び出すことができるシェルスクリプトを作成することでした。
#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
printf 'Usage: respath path [working-directory]\n' >&2
exit 1
fi
cantGoUp=
path=$1
if [ $# -gt 1 ]; then
cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks
#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
printf '%s\n' "$path"
exit 0
fi
#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
case "$path" in
..*)
if [ "$cwd" = '/' ]; then
printf 'Invalid relative path\n' >&2
exit 1
fi
if [ "$path" = '..' ]; then
path=
else
path=`echo "$path" | sed 's;^\.\./;;'`
fi
cwd=`dirname $cwd`
;;
*)
break
;;
esac
done
cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
if [ -z "$cwd" ]; then
cwd='/'
fi
printf '%s\n' "$cwd"
else
printf '%s/%s\n' "$cwd" "$path"
fi
このソリューションは、移植性のためにBourne Shell用に書かれています。 「respath.sh」というスクリプトに入れました。
スクリプトは次のように使用できます。
respath.sh '/path/to/file'
それとも
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
スクリプトは、2 番目の引数のパスを始点として使用して、1 番目の引数のパスを解析します。最初の引数だけが指定された場合、スクリプトは現在の作業ディレクトリに基づいてパスを確認します。