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


33

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

スクリプトと同じディレクトリの下に別のテキストファイルがあります。スクリプト内のテキストファイルをどのように参照するのでしょうか。

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



確実にはbashスクリプトファイルのパスを取得するにはどのようにこの質問の答えは、私は私の道にそれを追加しました:stackoverflow.com/q/4774054/1695680
ThorSummoner

回答:


24

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

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

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

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

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

    MYDIR="${MYSELF%/*}"

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

[編集]:Calebrealpathreadlink -f 提案する以上の利点はないと思われるので、おそらく後者を使用した方が良いでしょう。私のタイミングテストは、実際に高速であることを示しています。


問題ない。ところで、realpathあなたのシステムのどこから来たのか。(それを持っていない他の人のためにあなたが使用することができますreadlink -f
カレブ

@Caleb実際には、これは標準のGNUユーティリティ(coreutils)のセットに属していると思っていましたが、今では別のパッケージであることがわかります
rozcietrzewiacz

@rozcietrzewiacz は、GNU coreutilsに含まrealpathれていた以前readlink -f(およびreadlinkIIRCさえ)に遡ります(同様のツールがいくつかありました。readlink -f最終的には事実上の標準になりました)。realpathまだ使用しているスクリプトとの互換性のためにのみ保持されます。
ジル「SO-悪であるのをやめる」

が存在しない場所$(dirname "$(which "$0")")より$(dirname $0)も優れている点whichは何ですか?同じじゃない?
UlfR

readlink -fMac OS X 10.11.6では動作しないようですrealpathが、そのまま使用できます。
-Grav

9

私のシステムではありませんrealpathようrozcietrzewiaczによって提案されました

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

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

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

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

@rozcietrzewiacz:私は実際にあなたのwhich提案だけに言及していませんでした。このため、通常の解決策は、どちらかだけの関係dirnameかの組み合わせcdpwdサブシェルでは。Readlinkにはここでの利点があります。とにかくrealpath、単なる単なるラッパーのようreadlink -fです。
カレブ

どのようrealpathに違うのか分からないreadlink -f。(に対してwhich)同じ結果が得られることしかわかりません。
rozcietrzewiacz

ことを覚えておいてくださいreadlink -f(GNUのcoreutilsのから)が存在するパスの最後の要素を必要としません、readlink -eん、しかしによってサポートされていないbusybox readlinkの模倣行動、-eその中-fのオプション。
dragon788

8

$0スクリプト内では、スクリプトへの完全なパスになり、完全なパスをdirname取り、ディレクトリだけを提供するため、これをcatテキストファイルに行うことができます。

$ cat "$(dirname -- "$0")/textfile"

これはなしrealpath $0でも機能するように見えますが、「$0スクリプト内ではスクリプトへのフルパスになります」と言うのは間違っています。
rozcietrzewiacz

@rozどのように?
マイケルMrozek

1
$0は、実行されたときのコマンド../script.shです。
rozcietrzewiacz

そのため、実際に$(dirname "$0")は、絶対パスではなく、呼び出されたコマンドの一部として、スクリプトへの相対パスを返します。これにより、実行中にディレクトリを変更するスクリプトで問題が発生する可能性があります。
rozcietrzewiacz

@rozああ、面白い。だから私は彼が名前でパス上の何かを呼び出しているので、ここでは問題を引き起こさないと思うが、それは他のものを壊すだろう。おかげで
マイケルMrozek

4

これをスクリプトの先頭に配置できます。

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

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

ソース:http : //mywiki.wooledge.org/BashFAQ/028


2

私はこれらを試していましたが、realpathは私にはうまくいきませんでした。私が行った解決策は次のとおりです。

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

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


1
良いが、シンボリックリンクをたどらない。これを試してください:SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
OronNavon


0

私はいつもwhichPATHから実行可能ファイルのフルパスを見つけるために使用します。例えば:

which python

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

wp=`which python`
dn=`dirname $wp`
ls $dn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.