bashスクリプトファイルがあります。このファイルは、$ PATHに追加されたディレクトリの下に置かれ、任意のディレクトリからスクリプトを呼び出すことができます。
スクリプトと同じディレクトリの下に別のテキストファイルがあります。スクリプト内のテキストファイルをどのように参照するのでしょうか。
たとえば、スクリプトがテキストファイルの内容を出力するだけの場合、スクリプトはcat textfile別のディレクトリから呼び出されるとテキストファイルが見つからないため、機能しません。
bashスクリプトファイルがあります。このファイルは、$ PATHに追加されたディレクトリの下に置かれ、任意のディレクトリからスクリプトを呼び出すことができます。
スクリプトと同じディレクトリの下に別のテキストファイルがあります。スクリプト内のテキストファイルをどのように参照するのでしょうか。
たとえば、スクリプトがテキストファイルの内容を出力するだけの場合、スクリプトはcat textfile別のディレクトリから呼び出されるとテキストファイルが見つからないため、機能しません。
回答:
シンボリックリンクがない限り(パス展開またはスクリプト自体に)、これらは同じように機能します。
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
上記のいずれかの2ステップバージョン:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
スクリプトへの途中にシンボリックリンクがある場合which、そのリンクの解決を含まない回答を提供します。realpathシステムにデフォルトでインストールされていない場合は、ここで見つけることができます。
[編集]:Calebrealpathがreadlink -f 提案する以上の利点はないと思われるので、おそらく後者を使用した方が良いでしょう。私のタイミングテストは、実際に高速であることを示しています。
realpathあなたのシステムのどこから来たのか。(それを持っていない他の人のためにあなたが使用することができますreadlink -f
realpathれていた以前readlink -f(およびreadlinkIIRCさえ)に遡ります(同様のツールがいくつかありました。readlink -f最終的には事実上の標準になりました)。realpathまだ使用しているスクリプトとの互換性のためにのみ保持されます。
$(dirname "$(which "$0")")より$(dirname $0)も優れている点whichは何ですか?同じじゃない?
readlink -fMac OS X 10.11.6では動作しないようですrealpathが、そのまま使用できます。
私のシステムではありませんrealpathようrozcietrzewiaczによって提案されました。
これを行うには、readlinkコマンドを使用します。解析whichまたは他のソリューションよりもこれを使用する利点は、実行されたパスまたはファイル名の一部がシンボリックリンクであっても、実際のファイルがあるディレクトリを見つけることができることです。
MYDIR="$(dirname "$(readlink -f "$0")")"
テキストファイルを次のような変数に読み込むことができます。
TEXTFILE="$(<$MYDIR/textfile)"
which提案だけに言及していませんでした。このため、通常の解決策は、どちらかだけの関係dirnameかの組み合わせcdとpwdサブシェルでは。Readlinkにはここでの利点があります。とにかくrealpath、単なる単なるラッパーのようreadlink -fです。
realpathに違うのか分からないreadlink -f。(に対してwhich)同じ結果が得られることしかわかりません。
readlink -f(GNUのcoreutilsのから)が存在するパスの最後の要素を必要としません、readlink -eん、しかしによってサポートされていないbusybox readlinkの模倣行動、-eその中-fのオプション。
$0スクリプト内では、スクリプトへの完全なパスになり、完全なパスをdirname取り、ディレクトリだけを提供するため、これをcatテキストファイルに行うことができます。
$ cat "$(dirname -- "$0")/textfile"
realpath $0でも機能するように見えますが、「$0スクリプト内ではスクリプトへのフルパスになります」と言うのは間違っています。
$0は、実行されたときのコマンド../script.shです。
$(dirname "$0")は、絶対パスではなく、呼び出されたコマンドの一部として、スクリプトへの相対パスを返します。これにより、実行中にディレクトリを変更するスクリプトで問題が発生する可能性があります。
これをスクリプトの先頭に配置できます。
cd "${BASH_SOURCE%/*}" || exit
BASH_SOURCE内部bash変数は、実際にはパス名の配列です。「$ BASH_SOURCE」などの単純な文字列として展開すると、現在実行中の関数またはスクリプトのパス名である最初の要素が取得されます。
私はこれらを試していましたが、realpathは私にはうまくいきませんでした。私が行った解決策は次のとおりです。
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
これは今のところうまくいきました。アプローチに潜在的な問題があるかどうかを知りたいです。
SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
私が使う:
#! /bin/sh -
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) || exit
dosomethingwith "${dir%/}/some-file"
これはPOSIXであるとのdirnameに限り、動作するはず$0改行文字で終わっていない、ではない-と$CDPATH(と設定されていない可能性が他のいくつかのコーナーケースをスクリプトがルックアップされなかった場合に$PATH)。