web-dev-qa-db-ja.com

関数内から関数名を決定する方法

次のようなBashスクリプトがある場合:

#!/bin/bash

f() {
  # echo function name, "f" in this case
}

これを行う方法はありますか?これは、次のようなヘルプメッセージで使用できます。

printf "Usage: %s: blah blah blah \n" $(basename $0) >&2; 

この場合にのみ、私が欲しかったのは$0、これはスクリプトのファイル名です。

131
Yan

bash${FUNCNAME[0]}を使用して、関数名を取得できます。

189
TheBonsai

Bash Reference Manual から:

FUNCNAME

現在実行呼び出しスタックにあるすべてのシェル関数の名前を含む配列変数。インデックス0の要素は、現在実行中のシェル関数の名前です。一番下の要素(最高のインデックスを持つ要素)は「メイン」です。この変数は、シェル関数が実行されている場合にのみ存在します。 FUNCNAMEへの割り当ては効果がなく、エラーステータスを返します。 FUNCNAMEが設定されていない場合、後でリセットされても、その特別なプロパティは失われます。

この変数は、BASH_LINENOおよびBASH_SOURCEで使用できます。 FUNCNAMEの各要素には、BASH_LINENOおよびBASH_SOURCEに対応する要素があり、コールスタックを記述します。たとえば、$ {FUNCNAME [$ i]}は、行番号$ {BASH_LINENO [$ i]}のファイル$ {BASH_SOURCE [$ i + 1]}から呼び出されました。呼び出し元のビルトインは、この情報を使用して現在の呼び出しスタックを表示します。

インデックスなしでbash配列にアクセスすると、配列の最初の要素が返されるため、$FUNCNAMEは、単純な場合に機能して、すぐに現在の関数の名前を提供しますが、呼び出しスタック内の他のすべての関数も含みます。例えば:

# in a file "foobar"
function foo {
    echo foo
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

function foobar {
    echo "$(foo)bar"
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

foobar

出力されます:

$ bash foobar
In function foo: FUNCNAME=foo foobar main
foobar
In function foobar: FUNCNAME=foobar main
67
bschlueter

私が使う ${FUNCNAME[0]}現在の関数名を出力する

34
Verdigrass