Как определить имя функции изнутри функции - PullRequest
128 голосов
/ 03 декабря 2009

Если у меня есть скрипт на Bash, например:

#!/bin/bash

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

Есть ли способ сделать это? Это может быть использовано в справочных сообщениях, таких как

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

Только в этом случае мне нужно было не $0, которое является именем файла скрипта.

Ответы [ 3 ]

185 голосов
/ 03 декабря 2009

Вы можете использовать ${FUNCNAME[0]} в bash, чтобы получить имя функции.

66 голосов
/ 13 апреля 2016

Из Справочного руководства Bash :

имя_функция

Переменная массива, содержащая имена всех функций оболочки, которые в данный момент находятся в стеке вызовов выполнения. Элемент с индексом 0 - это имя любой выполняемой в данный момент функции оболочки. Самый нижний элемент (с наивысшим индексом) является «основным». Эта переменная существует только при выполнении функции оболочки. Назначения FUNCNAME не имеют никакого эффекта и возвращают статус ошибки. Если FUNCNAME не установлено, оно теряет свои специальные свойства, даже если оно впоследствии сбрасывается.

Эта переменная может использоваться с BASH_LINENO и BASH_SOURCE. Каждый элемент FUNCNAME имеет соответствующие элементы в BASH_LINENO и BASH_SOURCE для описания стека вызовов. Например, $ {FUNCNAME [$ i]} был вызван из файла $ {BASH_SOURCE [$ i + 1]} по номеру строки $ {BASH_LINENO [$ i]}. Встроенная функция вызывающего абонента отображает текущий стек вызовов, используя эту информацию.

Когда доступ к массивам 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
33 голосов
/ 19 января 2016

Я использую ${FUNCNAME[0]} для печати названия текущей функции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...