web-dev-qa-db-ja.com

$ PATHにあるスクリプトと同じディレクトリにあるファイルを参照します

$ PATHに追加されたディレクトリの下に置かれたbashスクリプトファイルがあるので、任意のディレクトリからスクリプトを呼び出すことができます。

スクリプトと同じディレクトリの下に別のテキストファイルがあります。スクリプトでテキストファイルを参照する方法を教えてください。

たとえば、スクリプトがテキストファイルの内容を出力するだけの場合、cat textfileは機能しません。別のディレクトリからスクリプトを呼び出すと、テキストファイルが見つかりません。

37
Tim

(パスの展開またはスクリプト自体に)シンボリックリンクがない限り、これらは同じように機能します。

  • MYDIR="$(dirname "$(realpath "$0")")"

  • MYDIR="$(dirname "$(which "$0")")"

  • 上記のいずれかの2ステップバージョン:

    MYSELF="$(realpath "$0")"

    MYDIR="${MYSELF%/*}"

スクリプトへの途中にシンボリックリンクがある場合、whichはそのリンクの解決を含まない回答を提供します。 realpathがデフォルトでシステムにインストールされていない場合は、 ここで見つけることができます

[EDIT]:realpathreadlink -fよりも有利ではないようです Calebの提案 =、おそらく後者を使用する方が良いでしょう。私のタイミングテストは、それが実際に速いことを示しています。

26
rozcietrzewiacz

私のシステムにはrealpathがありません rozcietrzewiaczが推奨

これは、readlinkコマンドを使用して実行できます。これを解析whichまたは他のソリューションよりも使用する利点は、パスの一部または実行されたファイル名がシンボリックリンクであったとしても、実際のファイルがあったディレクトリを見つけることができるということです。

MYDIR="$(dirname "$(readlink -f "$0")")"

次に、テキストファイルを次のような変数に読み込むことができます。

TEXTFILE="$(<$MYDIR/textfile)"
13
Caleb

スクリプト内の$0はスクリプトへの完全パスであり、dirnameは完全パスを取得してディレクトリのみを提供するため、これをcat textfileに実行できます。

$ cat "$(dirname -- "$0")/textfile"
8
Michael Mrozek

これをスクリプトの先頭に置くことができます:

cd "${BASH_SOURCE%/*}" || exit

BASH_SOURCE内部bash変数は、実際にはパス名の配列です。単純な文字列として展開すると、 "$ BASH_SOURCE"、最初の要素を取得します。これは、現在実行中の関数またはスクリプトのパス名です。

出典: http://mywiki.wooledge.org/BashFAQ/028

4
Big McLargeHuge

私はこれらを試してみましたが、realpathはうまくいきませんでした。私が行った解決策は:

SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

これまでのところうまくいきました。アプローチに潜在的な問題があるかどうか知りたいのですが。

2
Brettski

私が使う:

#! /bin/sh -
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) || exit
dosomethingwith "${dir%/}/some-file"

どちらがPOSIXであり、$0のdirnameが改行文字で終わっておらず、-でなく、$CDPATHが設定されていない(そして おそらくいくつかのその他のコーナーケース スクリプトが$PATHで検索されなかった場合)。

1

私は常にwhichを使用して、PATHから実行可能ファイルの完全パスを見つけます。例えば:

which python

これをdirnameコマンドと組み合わせると、次のようになります。

wp=`which python`
dn=`dirname $wp`
ls $dn
0
Michael Dillon