web-dev-qa-db-fra.com

Comment déterminer le nom d'une fonction à l'intérieur d'une fonction

Si j'ai un script Bash comme:

#!/bin/bash

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

Est-ce qu'il y a un moyen de faire ça? Cela pourrait être utilisé dans des messages d'aide tels que

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

Seulement dans ce cas, ce que je voulais, ce n'est pas $0, qui est le nom de fichier du script.

131
Yan

Vous pouvez utiliser ${FUNCNAME[0]} dans bash pour obtenir le nom de la fonction.

189
TheBonsai

Dans le Manuel de référence Bash :

FUNCNAME

Variable de tableau contenant les noms de toutes les fonctions Shell actuellement dans la pile des appels d'exécution. L'élément avec l'index 0 est le nom de toute fonction Shell en cours d'exécution. L'élément le plus bas (celui dont l'indice est le plus élevé) est "principal". Cette variable existe uniquement lorsqu'une fonction Shell est en cours d'exécution. Les affectations à FUNCNAME n'ont aucun effet et renvoient un état d'erreur. Si FUNCNAME n'est pas défini, il perd ses propriétés spéciales, même s'il est réinitialisé par la suite.

Cette variable peut être utilisée avec BASH_LINENO et BASH_SOURCE. Chaque élément de FUNCNAME a des éléments correspondants dans BASH_LINENO et BASH_SOURCE pour décrire la pile d'appels. Par exemple, $ {FUNCNAME [$ i]} a été appelé à partir du fichier $ {BASH_SOURCE [$ i + 1]} au numéro de ligne $ {BASH_LINENO [$ i]}. La fonction intégrée de l'appelant affiche la pile d'appels actuelle à l'aide de ces informations.

Lorsque les tableaux bash sont accessibles sans index, le premier élément du tableau est renvoyé, donc $FUNCNAME fonctionnera dans des cas simples pour fournir le nom de la fonction immédiatement courante, mais il contient également toutes les autres fonctions de la pile d'appels. Par exemple:

# 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

Sortira:

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

J'utilise ${FUNCNAME[0]} pour imprimer le nom de la fonction actuelle

34
Verdigrass