完全なパスを知る必要がある Bash スクリプトがあります。相対パスや奇妙なパスにならずに、広く互換性のある方法でそれを実行しようとしています。sh、csh などではなく、Bash のみをサポートする必要があります。
これまでに発見したこと:
受け入れられた答えはBashスクリプトのソースディレクトリを取得するは、 を介してスクリプトのパスを取得しますが、これは問題ありません
dirname $0
。ただし、のような相対.
パスが返される可能性があり、スクリプト内のディレクトリを変更して、パスがスクリプトのディレクトリを指すようにしたい場合には問題になります。それでも、 はdirname
パズルの一部になります。受け入れられた答えはOS XでのBashスクリプトの絶対パス (OS X 固有ですが、答えは OS X に関係なく機能します)は、 が相対的かどうかをテストし
$0
、相対的である場合はそれを先頭に追加する関数を提供し$PWD
ます。ただし、結果には相対ビットが含まれる場合があります (全体的には絶対的ですが)。たとえば、スクリプトがt
ディレクトリにあり/usr/bin
、そのディレクトリでスクリプトを実行するために入力する/usr
と(はい、これは複雑です)、スクリプトのディレクトリ パスとしてbin/../bin/t
になります。これは機能しますが.../usr/bin/../bin
ソリューション
readlink
このページ、次のようになります。# Absolute path to this script. /home/user/bin/foo.sh SCRIPT=$(readlink -f $0) # Absolute path this script is in. /home/user/bin SCRIPTPATH=`dirname $SCRIPT`
しかし
readlink
、これは POSIX ではなく、どうやらソリューションは GNU に依存しておりreadlink
、BSD は何らかの理由で動作しません (確認するための BSD のようなシステムにアクセスできません)。
つまり、さまざまな方法がありますが、それぞれに注意点があります。
もっと良い方法は何でしょうか? ここでの「良い」とは、次のことを意味します。
- 絶対パスを教えてくれます。
- 複雑な方法で呼び出された場合でも、奇妙な部分を取り除きます (上記のコメント 2 を参照)。 (たとえば、パスを少なくとも適度に正規化します。)
- Bash のスタイルや、*nix システムの最も人気のあるフレーバー (GNU/Linux、BSD、OS X などの BSD 系システムなど) にほぼ確実に存在するもののみに依存します。
- 可能であれば外部プログラムの呼び出しを避けます (例: Bash 組み込みを優先します)。
- (更新しました。お知らせいただきありがとうございます。ウィッチ) シンボリックリンクを解決する必要はありません (実際、シンボリックリンクをそのままにしておく方がよいのですが、これは必須ではありません)。
ベストアンサー1
これが私が思いついたものです(編集:いくつかの調整を加えたもの)sfstewman、レビグロッカー、カイル・ストランド、 そしてロブ・ケネディ) は、私の「より良い」基準にほぼ適合しているようです。
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
この行は特に回りくどいように思えますが、スペースとシンボリックリンクを適切に処理するためにはSCRIPTPATH
必要なのです。SCRIPTPATH=`pwd`
出力リダイレクト( )を含めることで、まれに、周囲のキャプチャに干渉する出力を生成する可能性がある>/dev/null 2>&1
場合に対処します。(例:cd
$( ... )
cd
ls
ディレクトリにも上書きされる切り替えた後。
また、アクセス可能なファイル システム内のファイルから取得されていないスクリプトを実行するなどの難解な状況 (これは完全に可能です) は、そこでは (または私が見た他のどの回答でも) 対応されていないことに注意してください。
afterと before は、--
ディレクトリが で始まる場合のものです。cd
"$0"
-