함수 내부에서 함수 이름을 결정하는 방법


163

내가 Bash 스크립트를 가지고 있다면 :

#!/bin/bash

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

이것을 할 수있는 방법이 있습니까? 이것은 다음과 같은 도움말 메시지에서 사용될 수 있습니다

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

이 경우에만 내가 원하는 것은 not $0, 이것이 스크립트의 파일 이름입니다.


2
관련 : 배시 로깅 워크 그 용도의 FUNCNAME배열과 다른 배시 변수 : github.com/codeforester/base/blob/master/lib/stdlib.sh이 . 기능을 참조 log_debug_enter하고 log_debug_leave, 특히있다.
codeforester

답변:


236

${FUNCNAME[0]}in bash을 사용 하여 함수 이름을 얻을 수 있습니다 .


79

로부터 배쉬 참조 설명서 :

기능 명

현재 실행 호출 스택에있는 모든 쉘 함수의 이름을 포함하는 배열 변수입니다. 인덱스가 0 인 요소는 현재 실행중인 쉘 함수의 이름입니다. 맨 아래 요소 (인덱스가 가장 높은 요소)는 "main"입니다. 이 변수는 쉘 기능이 실행될 때만 존재합니다. 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

6
나는 아직도 그것을 얻지 못한다. [0]장식되지 않은 변수에 액세스하여 묵시적을 추가하는 이유는 무엇 입니까?
Tom Hale

15
변수의 실제 유형을기만적이고 무지하기 때문에? 물론, 항상 필요한 것은 아니지만 다른 많은 bash-ism과 마찬가지로 게으른 규칙입니다. 모호한 것보다 명확하게하는 것이 좋습니다.
bschlueter

36

${FUNCNAME[0]}현재 기능 이름을 인쇄 하는 데 사용 합니다


@bschlueter 그러나 Bash의 배열처럼 취급하지 않고 배열을 참조하면 첫 번째 값만 인쇄됩니다. 따라서 받아 들여진 대답은 어떻게 잘못 되었습니까?
Alexej Magura

4
물론, 편리하지만 유지 관리 및 테스트에는 끔찍합니다. 게으르지 말고 명시 적이어야합니다.
bschlueter

1

다른 예시:

# in a file "foobar"
foo() {
    echo "$FUNCNAME fuction begins"
}

foobar() {
    echo "$FUNCNAME fuction begins"
}

echo 'begin main'
foo
foobar
echo 'end main'

출력합니다 :

begin main
foo fuction begins
foobar fuction begins
end main

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.