2009-12-02 12 views
97

Si tengo un script bash:Cómo determinar el nombre de la función dentro de una función

#/bin/bash 

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

¿Hay alguna manera de hacer esto? Esto podría ser utilizado en los mensajes de ayuda tales como

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

Sólo en este caso, lo que quería decir que no $0, que es el nombre de archivo del script.

Respuesta

137

Puede usar ${FUNCNAME[0]} en bash para obtener el nombre de la función.

24

utilizo ${FUNCNAME[0]} para imprimir nombre de la función actual

+0

Esta debe ser la respuesta aceptada, voy a añadir mi propia para explicar por qué. – bschlueter

+0

@bschlueter pero cuando hace referencia a una matriz sin tratarla como una matriz en Bash, solo imprime el primer valor; por lo tanto, ¿cómo es incorrecta la respuesta aceptada? –

+1

Claro, y eso es conveniente, pero terrible para el mantenimiento y las pruebas. No seas perezoso, sé explícito. – bschlueter

41

Desde el Bash Reference Manual:

FUNCNAME

una variable de matriz que contiene los nombres de todas las funciones de shell actualmente en la pila de llamadas ejecución. El elemento con índice 0 es el nombre de cualquier función de shell actualmente en ejecución. El elemento inferior (el que tiene el índice más alto) es "principal". Esta variable existe solo cuando se está ejecutando una función de shell. Las asignaciones a FUNCNAME no tienen ningún efecto y devuelven un estado de error. Si FUNCNAME no está configurado, pierde sus propiedades especiales, incluso si se restablece posteriormente.

Esta variable se puede usar con BASH_LINENO y BASH_SOURCE. Cada elemento de FUNCNAME tiene elementos correspondientes en BASH_LINENO y BASH_SOURCE para describir la pila de llamadas. Por ejemplo, se llamó a $ {FUNCNAME [$ i]} desde el archivo $ {BASH_SOURCE [$ i + 1]} en el número de línea $ {BASH_LINENO [$ i]}. El builtin de quien llama muestra la pila de llamadas actual utilizando esta información.

Cuando se accede a arrays golpe sin un índice será devuelto el primer elemento de la matriz, por lo $FUNCNAME funcionará en casos simples para proporcionar el nombre de la función inmediatamente corriente, pero también contiene todas las otras funciones en el pila de llamadas. Por ejemplo:

# 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 

salida será:

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

Todavía no lo entiendo. ¿Por qué agregar '[0]' si está implícito al acceder a la variable no decorada? –

+5

¿Porque es engañoso e ignorante del tipo real de la variable? Claro, no siempre es necesario, pero como muchos otros bash-ismos, es una convención perezosa. Es mejor ser explícito que ambiguo. – bschlueter

Cuestiones relacionadas