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


13

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

bashスクリプトで使用される関数をどのように定義できますか?


しかし、私の.bash_profileは基本的に.basrcファイルを読み取るため、ログインシェルまたは非ログインシェルを使用する場合でも結果は同じになると予想されます。
オンチュレニオ

/bin/shシバンラインで使用していますか?
ケビン

回答:


9

~/.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です。これははるかに移植性が高く、特定の方法で設定されている環境に依存しません。


function myFunction { ... }inのような関数を宣言するだけで、準備完了~/.bash_profileです。
両生類

(関数を使用してファイルをソースすることに関して)あなたの答えを適切に理解できた場合、これはすべてのスクリプトで明示的にファイルを取得する必要があることを意味し、かなり面倒です。これは、すべてのスクリプトで関数自体を単にコピーアンドペーストするよりもそれほど複雑ではありません。確かにいくつかの行を保存しますが、それだけです。ただし、exportソリューションは適切に機能するようです。ありがとう。
オンチュレニオ

@foampile、これはまさに私がやったことであり、スクリプトから関数を呼び出すときに機能しません。
オンチュレニオ

1
@Onturenio:@ chris-downが提案する2番目の方法の方が確かに優れています:1)誰かがスクリプトを読んだとき、彼らはいくつかのfoo機能を必要とすることを認識していますfile2)file呼び出しシェルfooスクリプトを呼び出す前に変更されませんでした。fileたとえば、安全性チェックを追加して、改ざんされていないことを確認できます。(簡単ではありませんが、可能です)。(まあ、あなたはまた、定義されたfooという関数にこれらのチェックを行うことができます...しかし、あなたは、私は方法2がきれいだと思います^^私のドリフトを取得します。)3)fileだけでなく、より多くの、必要なものが含まれます。
オリビエデュラック

8

.bashrc対話型シェルによってのみ読み取られます。バッシュは読まないbashはこの点で風変わりです:。(実際には、それは単純化し過ぎだ.bashrcインタラクティブ、それがログインシェルだ場合か、例外も例外にあります:bashの者の親プロセスがある場合rshdsshd、その後のbashを読んでありません.bashrc、インタラクティブかどうか)

関数定義を既知の場所のファイルに配置し、組み込みの.(スペルも同じsource)を使用して、そのファイルをスクリプトに含めます。

$ cat ~/lib/bash/my_functions.bash
foo () {

$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar

必要に応じて、kshの自動読み込み機能を使用できます。各関数定義を、関数と同じ名前のファイルに入れます。FPATH変数内の関数定義を含むディレクトリを一覧表示します(コロンで区切られたディレクトリのリスト)。autoloadオンデマンドではなく実際に関数をすぐにロードするkshの大まかな近似を次に示します。

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"
}

オートロードの場合は+1ですが、bashに付属しているものを使用することをお勧めします。最新のものは遅延ロードをサポートしています。
ヒトデ

0

機能が必要ですか?そうでない場合は、ロジックを別のスタンドアロンBashスクリプトに引き出してください$PATH。たとえば、私はこれを私の~/.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、他のスクリプトから実行できます。

wanipスタンドアロンのBashスクリプトを使用するのが好きです。このロジックを一般的に利用したいということを思い出させます(現在のインタラクティブなBashセッションだけでなく)。このスクリプトは、同じロジックとドキュメントをうまくカプセル化します。

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