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
(およびreadlink
IIRCさえ)に遡ります(同様のツールがいくつかありました。readlink -f
最終的には事実上の標準になりました)。realpath
まだ使用しているスクリプトとの互換性のためにのみ保持されます。
$(dirname "$(which "$0")")
より$(dirname $0)
も優れている点which
は何ですか?同じじゃない?
readlink -f
Mac 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
)。