web-dev-qa-db-ja.com

シェルで関数をエクスポートする

親シェルから関数をエクスポートする方法を教えてください(bash、sh、またはksh)。その関数は、親プロセスから起動されたすべての子プロセスで使用できますか?

85

export -f機能はBashに固有です:

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

#!/bin/bash
echo $(plus1 $(($1 * $2)) )
102

shでは、notは関数をエクスポートできません。これは Charles Duffyによって記されている です。

8
anol

kshまたはzshを使用している場合:

環境変数FPATHを使用して、すべての関数を配置できます。

インタラクティブインタープリターでFPATHが設定されており、現在のシェル環境またはPATHでコマンドまたは関数が見つからない場合、そこにリストされているディレクトリで、次の名前のファイルの存在が検索されます。欠落しているコマンド。見つかった場合は、現在のシェル環境をソースとし、関数を定義することが期待されます。

そのため、すべての関数をFPATHの場所に配置でき、子スクリプトもそれを見つけることができます。

シェルスクリプトでautoloadコマンドを使用して、必要な機能をロードできます。

autoload fun_a fun_b

zshでは、autoloadが機能するためにFPATHが必要です。kshとその近縁で、それはFPATHで定義された関数が、直接定義された場合と同様に、PATH内の通常のコマンドをオーバーライドするだけだと考えています。

FPATHおよびautoloadの詳細:

( )を使用してサブシェルを作成すると、すべての定義、パラメーター、およびシェル変数のスナップショットを継承します。

プログラムのように実行する場合、定義を.bashrcに入れることができます。

既存のスクリプトを偽装してラッパーまたはPATHコマンドの置換を実行しようとする場合、.bashrcは実行の詳細に応じて機能します。そうでない場合は、代わりに、関数を定義するインクルードファイルの.またはsourceを実行するラッパースクリプトを実行し、その後、シェルスクリプトで同じコマンドを置換するコマンドを実行できます。 。

ラッパースクリプトは次のようになります。

script=$1
shift
. include.sh
. $script "$@"

最初のパラメーターは実際のスクリプトの名前であり、残りのパラメーターはargsであり、代わりに上記のスクリプトが実行されるという考え方です。

1
DigitalRoss
declare -x -f NAME

詳細情報

-fアクションまたは表示を関数名と定義に制限する
-x NAMEをエクスポートする
1
Steven Penny

関数は本来エクスポートできません。ただし、文字列をエクスポートすることができますので、ここで少しコツがあります。

func="$(typeset -f funcname)"
export func

関数をインポートするには、エクスポートされた文字列から関数を再定義します。

# in subshell
eval "$func"
0
iBug