私はSolaris 10を使用しており、ksh(88)、bash(3.00)、およびzsh(4.2.1)を使用して以下をテストしました。
次のコードは結果を生成しません。
function foo {
echo "Hello World"
}
find somedir -exec foo \;
findは複数のファイルと一致し(代替として表示されます-exec ...
)、-print
関数はfind
外部から呼び出されると完全に機能します。
man find
このページの内容は次のとおりです-exec
。
-exec コマンド 実行されたコマンドが以下を返すと真です。 0 値は終了状態として使用されます。終わり コマンドはエスケープ文字で区切る必要があります。 セミコロン(;)。コマンドパラメータ{}は 現在のパス名に置き換えます。もし -execの最後の引数は{}です。 セミコロン(;)の代わりに+を指定してください。 コマンドはあまり頻繁に呼び出されません。 {} はパス名グループに置き換えられます。もし このコマンドを呼び出すと返されます。 終了状態でゼロ以外の値を探します。 ゼロ以外の終了状態を返します。
おそらく次のようにすることができます。
for f in $(find somedir); do
foo
done
しかし、フィールド区切り記号の問題に対処するのは怖いです。
呼び出しでシェル関数を呼び出すことは可能ですか(同じスクリプトで定義されているので、スコープの問題を心配する必要はありません)find ... -exec ...
。
私は両方とも試してみましたが、/usr/bin/find
同じ/bin/find
結果を得ました。
ベストアンサー1
Afunction
はシェル固有の関数なので、find -exec
使用する前にシェルを作成し、そのシェルで関数を定義する必要があります。それは次のとおりです。
find ... -exec ksh -c '
function foo {
echo blan: "$@"
}
foo "$@"' ksh {} +
bash
環境を介して機能をエクスポートできるのでexport -f
(bashで)、次のことができます。
foo() { ...; }
export -f foo
find ... -exec bash -c 'foo "$@"' bash {} +
ksh88
この関数は(環境を介さずに)エクスポートする必要がありますtypeset -fx
が、実行中のシェーバンレススクリプトでのみ使用できるため、ksh
使用できませんksh -c
。
別のオプションは、次のことです。
find ... -exec ksh -c "
$(typeset -f foo)"'
foo "$@"' ksh {} +
つまり、インラインスクリプトから関数typeset -f
定義をダンプするために使用されます。他の機能を使用している場合は、その機能もダンプする必要があります。foo
foo
ps -f
あるいは、コマンドラインではなく環境変数を介して関数定義を渡すこともできます(出力に表示されます)。
FUNCDEFS=$(typeset -f foo) find ... -exec ksh -c '
eval "$FUNCDEFS" &&
unset -v FUNCDEFS &&
foo "$@"' ksh {} +
(unset -v FUNCDEFS
この機能で実行されるコマンドの環境を汚染しないようにfoo
(存在する場合))