
このコードスタックオーバーフローでスクリプトがシンボリックリンクを介して実行されても、スクリプト内でスクリプトの親ディレクトリのパス名を取得します。
if [ -L $0 ] ; then
DIR=$(dirname $(readlink -f $0)) ;
else
DIR=$(dirname $0) ;
fi ;
上記のコードは次のとおりですか?
DIR=$(dirname $(readlink -f $0)) ;
つまり、シンボリックリンクかどうかをテストし$0
、その場合は別のコマンドを実行する必要がありますか?
シンボリックリンクを$(dirname $(readlink -f $0))
使用したり使用したりするのではなく、単に使用しないでください。なぜですか?$0
特に$0
シンボリックリンクが含まれている場合はを使用してください$(dirname $(readlink -f $0))
。
シンボリックリンクではない場合は、以下を$0
使用するのが完璧に見えます$(dirname $(readlink -f $0))
。
$(readlink -f $0)
絶対パスを返し$0
、$(dirname $(readlink -f $0))
親ディレクトリの絶対パスを返します。$0
$(dirname $0)
返される親パスは、$0
絶対パスか相対パスかによって、$0
絶対パスか相対パスかによって異なります。DIR
元のコードでは、値が絶対パスか相対パスかは重要ではないと思います。どちらの場合も、値はの親DIR
ディレクトリを参照するためです$0
。元のコードでも$(dirname $(readlink -f $0))
同等ですか?$(dirname $0)
ありがとうございます。
答え1
"$0"
とを使用する必要がありますdirname "$()"
。
シェルテストはパスの最後のコンポーネントにのみ影響し、readlink -f
すべてのパスレベルに影響を与えるため、これらのコマンドは同じではありません。
mkdir physdir
touch physdir/file
ln -s physdir symlink
test -L symlink/file ; echo $?
1
test -L symlink ; echo $?
0
dirname symlink/file
symlink
dirname "$(readlink -f symlink/file)"
/crypto/home/hl/tmp/stackexchange/readlink/physdir
したがって、相対パスの場合、出力はまったく異なりますが、絶対パスの場合でもその中のシンボリックリンクディレクトリは異なります。
答え2
違いがあるかどうかは、使用しているUnixの正確な好みに依存していると思います。たとえば、OSXでは、readlinkにはフラグがなく、-f
次のように宣言します。
与えられた引数がシンボリックリンクでない場合、readlinkは何も印刷せず、エラーで終了します。
オペレーティングシステムがこのフラグをサポートしていることを知っていれば、-f
違いはありません。
実は-中フラグはおそらく使用するのに最も柔軟なフラグです。