~/.bashrc
ファイルにbash
関数を定義しました。これにより、シェルターミナルで使用できます。ただし、スクリプト内から呼び出すと存在しないようです。
スクリプトで使用するbash
関数を定義するにはどうすればよいですか?
~/.bash_profile
および~/.bashrc
はスクリプトによって読み取られず、関数はデフォルトではエクスポートされません。そのためには、export -f
を次のように使用できます。
$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; }
$ export -f foo
$ ./script
works
export -f foo
を~/.bash_profile
で呼び出して、ログイン後にこの関数をスクリプトで使用できるようにすることもできます。 export -f
は移植性がないことに注意してください。
より適切な解決策は、. file
を使用して関数を含むファイルを読み込むことです。これははるかに移植性が高く、特定の方法で設定されている環境に依存しません。
.bashrc
は対話型シェルでのみ読み取られます。 (実際、それは過度に単純化されています。bashはこの点で風変わりです。bashは、対話シェルであるかどうかにかかわらず、ログインシェルである場合は.bashrc
を読み取りません。そして、例外にも例外があります。bashの親プロセスがrshd
またはsshd
の場合、bashはインタラクティブかどうかにかかわらず、.bashrc
を読み取ります。
関数定義を既知の場所のファイルに入れ、.
(source
とも表記)ビルトインを使用して、そのファイルをスクリプトに含めます。
$ cat ~/lib/bash/my_functions.bash
foo () {
…
$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar
必要に応じて、kshのオートロード機能を使用できます。各関数定義を関数と同じ名前のファイルに入れます。関数定義を含むディレクトリをFPATH
変数にリストします(コロンで区切られたディレクトリのリスト)。次に、kshのautoload
の大まかな概算を示します。これは、オンデマンドではなく、関数をすぐに実際にロードします。
autoload () {
set -- "$(set +f; IFS=:;
for d in $FPATH; do
if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
done)"
[[ -n $1 ]] && . "$1"
}
必要関数ですか?そうでない場合は、ロジックを$PATH
の別のスタンドアロンBashスクリプトに引き出すことを検討してください。たとえば、これを~/.bashrc
に入れました:
# echo public IP address
alias wanip='Dig +short myip.opendns.com @resolver1.opendns.com'
~/bin
は$PATH
に含まれているため、次の内容で~/bin/wanip
を作成しました。
#!/bin/bash
# echo public IP address
Dig +short myip.opendns.com @resolver1.opendns.com
そしてchmod 0755 ~/bin/wanip
を実行して実行可能にしました。これで、他のスクリプトからwanip
を実行できます。
スタンドアロンのBashスクリプトにwanip
を含めるのが好きです。このロジックが一般的に利用可能になることを思い出します(現在のインタラクティブなBashセッションだけでなく)。スクリプトは、ロジックとドキュメントをうまくカプセル化します。