Bash의 호출자 인식 기능

Bash의 호출자 인식 기능

호출자에서 몇 가지 변수를 효과적으로 선언하고 할당해야 하는 함수(=callee)가 있습니다. 또한 발신자의 이름이 무엇인지 알 수 있어야 합니다.

eval지금은 전달된 변수에 호출자가 편집 할 문자열을 반환하여 전자를 달성합니다 .

 write_local_var_assignments variable_name; eval "$variable_name"

나는 호출자가 통과하도록 하거나 "$FUNCNAME"호출 수신자가 내장 기능을 호출 caller하고 그 출력을 구문 분석함으로써 후자를 달성할 수 있다고 상상합니다.

이 모든 솔루션은 매우 서투른 것 같아서 두 가지 질문이 있습니다.

  1. 호출자의 협조 없이 호출 수신자가 호출자의 컨텍스트에 지역 변수를 할당하는 것이 가능합니까?

즉, 다음을 압축할 수 있습니까?

 write_local_var_assignments variable_name; eval "$variable_name"

그냥

 run_local_var_assignments

?

  1. 함수 호출자의 이름을 얻는 더 좋은 방법이 있습니까? 구문 분석이나 명령 대체 없이 직접 결과를 얻는 것이 좋을 것입니다.

답변1

bash(및 ksh88, mksh, yash, dash) 에서 zsh지역 변수 범위 지정은 동적입니다.

이 코드는:

f() { a=2; echo "f: $a"; }
g() { local a=1; f; echo "g: $a"; }
a=0
g
echo "global: $a"

다음 출력을 생성합니다.

f: 2
g: 2
global: 0

에서 호출되었기 때문에 이는 f업데이트 g의 변수입니다 .$ag

이는 in 구문( ) typeset으로 선언된 함수에서 in 으로 선언된 변수 나 in 으로 선언된 변수와는 대조적입니다 .kshfunction f { ...; }ksh93privatezsh

f: 2
g: 1
global: 2

따라서 이 경우에는 아무것도 할 필요가 없습니다.

당신을 호출하는 함수의 이름을 알기 위해 에서 bash다음을 사용할 수 있습니다.${FUNCNAME[1]}.

이에 zsh상응하는 것은 다음과 같습니다 $funcstack[2].

$ zsh -c 'f() { echo $funcstack[2]; }; g() { f; }; g'
g
$ bash -c 'f() { echo "${FUNCNAME[1]}"; }; g() { f; }; g'
g

답변2

명령 대체를 사용해도 괜찮다면 자체 평가된 문자열을 호출자에게 반환하여 run_local_var_assignments생성된 함수를 호출할 수 있는 함수가 있습니다.

$(run_local_var_assignments)

함수는 다음과 같습니다:

emit () {
  local IFS=$'\n'
  printf 'eval eval %q' "$*"
}

위와 유사한 평가 문을 내보냅니다 eval "$variable_name". 결과 줄의 첫 번째 항목이므로 bash는 내보낸 eval을 명령으로 실행합니다.

함수에 의해 수행되는 이중 평가 및 %q 이스케이프는 단순히 개행 및 기타 특수 문자를 호출자에게 올바르게 전달하는 데 필요하기 때문에 존재합니다.

그러면 함수를 다음과 같이 작성할 수 있습니다.

run_local_var_assignments () {
  local assignments=()
  assignments+=( 'local myvar1="my value1"' )
  assignments+=( 'local myvar2="my value2"' )
  emit "${assignments[@]}"
}

할당은 마치 소스코드처럼 작성되기 때문에 값에 공백 같은 것은 위와 같이 따옴표가 필요합니다.

이 답변의 상단에서와 같이 명령 대체에서 이 함수를 호출하면 해당 값을 사용하여 호출자의 범위에 해당 지역 변수가 생성됩니다.

명령문 배열 대신 일반 문자열이나 heredoc을 사용할 수도 있지만 명령문 블록을 동적으로 작성하는 데 배열 방법이 유용한 경우가 많기 때문에 약간 더 복잡하더라도 이를 보여주고 싶다고 생각했습니다.

관련 정보