web-dev-qa-db-ja.com

さまざまなスクリプトで使用できるBash関数を定義する方法

~/.bashrcファイルにbash関数を定義しました。これにより、シェルターミナルで使用できます。ただし、スクリプト内から呼び出すと存在しないようです。

スクリプトで使用するbash関数を定義するにはどうすればよいですか?

13
Onturenio

~/.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を使用して関数を含むファイルを読み込むことです。これははるかに移植性が高く、特定の方法で設定されている環境に依存しません。

9
Chris Down

.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セッションだけでなく)。スクリプトは、ロジックとドキュメントをうまくカプセル化します。

0
Adam Monsen