1. ホーム
  2. バッシュ

[解決済み】Bashスクリプトが自分へのフルパスを取得する確実な方法【重複あり

2022-03-23 19:39:51

質問

フルパスを知る必要のあるBashスクリプトがあります。相対パスやファンキーなパスで終わることなく、広く互換性のある方法を見つけようとしています。私はBashだけをサポートすればよく、shやcshなどはサポートしない。

これまでに見つけたもの

  1. に対する回答として認められているのは Bashスクリプトのソースディレクトリを内部から取得する を経由してスクリプトのパスを取得するアドレスです。 dirname $0 を返すことがあります。 相対 パス(例えば . これは、スクリプト内のディレクトリを変更しても、パスがスクリプトのディレクトリを指すようにしたい場合に問題となります。それでも dirname はパズルの一部となります。

  2. の答えが受け入れられた。 OS XでのBashスクリプトの絶対パス (OS X 固有のものですが、答えは関係なく動作します) をテストする関数を提供します。 $0 が相対的に見える場合は $PWD を追加します。しかし、結果には相対的なビットが含まれることがあります(全体としては絶対的なものですが)。 t というディレクトリに /usr/bin で、あなたは /usr と入力すると bin/../bin/t を実行してみると(はい、複雑ですね)、結局は /usr/bin/../bin をスクリプトのディレクトリパスとして使用します。どの 動作 が、しかし...

  3. その 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 ライクなシステムにアクセスすることはできません)。

というわけで、いろいろな方法がありますが、どれも注意点がありますね。

より良い方法とは何でしょうか?ここで、"better"とは。

  • 絶対パスを教えてくれる
  • 複雑な方法で呼び出された場合でも、おかしな部分を取り除きます (上記#2に関するコメント参照)。(例えば、少なくとも適度にパスを正規化する)。
  • Bashイズムや、*nixシステム(GNU/Linux、BSD、OS XなどのBSDライクなシステム)の人気のあるフレーバーにほぼ確実に存在するものだけに依存します。
  • 可能な限り外部プログラムの呼び出しを避ける(例:Bashのビルトインを好んで使う)。
  • ( 更新 , ご指摘ありがとうございます。 ウィッチ ) シンボリックリンクを解決する必要はありません (実際、私はそれを放っておくことを望みますが、それは必要条件ではありません)。

解決方法は?

以下は、私が思いついたものです(編集:加えて、いくつかの微調整を sfstewman , レビグローカー , カイルストランド そして ロブ・ケネディ というのは、私の「より良い」という基準にほぼ合致しているように思います。

SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

その SCRIPTPATH の行は特に遠回りのように見えますが、私たちはこの行を SCRIPTPATH=`pwd` は、スペースとシンボリックリンクを適切に処理するためです。

出力リダイレクトを含むこと ( >/dev/null 2>&1 というまれなケースに対応します。 cd を妨害するような出力をする可能性があります。 $( ... ) をキャプチャします。(例えば cd にオーバーライドされ、さらに ls ディレクトリ に切り替わった後)

また、アクセス可能なファイルシステム内のファイルからではないスクリプトを実行するような難解な状況(これは完全に可能です)には対応していません(私が見た他の回答にもあります)のでご注意ください。

その -- の後に cd とその前に "$0" は、ディレクトリの先頭が - .