2009-12-02 14 views
97

Wenn ich so einen BASH Skript:Wie Funktionsnamen zu bestimmen, aus innerhalb einer Funktion

#/bin/bash 

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

Gibt es eine Möglichkeit, dies zu tun? Dies könnte in Hilfemeldungen verwendet werden, wie

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

Nur in diesem Fall, was ich wollte nicht $0, das der Dateiname des Skripts ist.

Antwort

137

Sie können ${FUNCNAME[0]} in bash verwenden, um den Funktionsnamen zu erhalten.

24

I verwenden ${FUNCNAME[0]} aktuelle Funktionsnamen

+0

Diese die akzeptierte Antwort sein sollte, werde ich meine eigenen hinzufügen zu erklären, warum. – bschlueter

+0

@bschlueter, aber wenn Sie ein Array referenzieren, ohne es wie ein Array in Bash zu behandeln, wird nur der erste Wert ausgegeben; daher, wie ist die angenommene antwort falsch? –

+1

Sicher, und das ist bequem, aber schrecklich für Wartung und Tests. Sei nicht faul, sei explizit. – bschlueter

41

Vom Bash Reference Manual drucken: die Namen aller Shell-Funktionen enthalten, gegenwärtig in dem Ausführungsaufrufstapel

FUNCNAME

eine Array-Variablen. Das Element mit Index 0 ist der Name einer aktuell ausgeführten Shell-Funktion. Das unterste Element (das mit dem höchsten Index) ist "main". Diese Variable existiert nur, wenn eine Shell-Funktion ausgeführt wird. Zuweisungen an FUNCNAME haben keine Auswirkung und geben einen Fehlerstatus zurück. Wenn FUNCTNAME nicht festgelegt ist, verliert es seine speziellen Eigenschaften, auch wenn es später zurückgesetzt wird.

Diese Variable kann mit BASH_LINENO und BASH_SOURCE verwendet werden. Jedes Element von FUNCNAME hat entsprechende Elemente in BASH_LINENO und BASH_SOURCE, um den Aufruf-Stack zu beschreiben. Zum Beispiel wurde $ {FUNCNAME [$ i]} aus der Datei $ {BASH_SOURCE [$ i + 1]} unter der Zeilennummer $ {BASH_LINENO [$ i]} aufgerufen. Der eingebaute Anrufer zeigt den aktuellen Anruf-Stack unter Verwendung dieser Information an.

Wenn bash Arrays ohne Index zugegriffen wird, das erste Element des Feldes wird zurückgegeben, so $FUNCNAME in einfachen Fällen funktionieren wird, den Namen der unmittelbar aktuellen Funktion zu liefern, aber es enthält auch alle andere Funktionen in dem Anrufliste. Zum Beispiel:

# 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 

Will Ausgang:

$ bash foobar 
In function foo: FUNCNAME=foo foobar main 
foobar 
In function foobar: FUNCNAME=foobar main 
+2

Ich verstehe es immer noch nicht. Warum fügen Sie das '[0]' hinzu, wenn es durch den Zugriff auf die undekorierte Variable angedeutet wird? –

+5

Weil es trügerisch ist und den tatsächlichen Typ der Variablen ignoriert? Sicher, es ist nicht immer notwendig, aber wie viele andere Bashismen ist es eine faule Konvention. Lieber explizit als mehrdeutig. – bschlueter

Verwandte Themen