호출자에서 여러 변수를 효과적으로 선언하고 할당해야 하는 함수(=callee)가 있습니다. 또한 발신자의 이름이 무엇인지도 알 수 있어야 합니다.
eval
이제 호출자가 편집한 전달된 변수에 문자열을 반환하여 전자를 수행합니다.
write_local_var_assignments variable_name; eval "$variable_name"
"$FUNCNAME"
나는 호출자가 통과하도록 하거나 호출 수신자가 caller
내장 함수를 호출하고 그 출력을 구문 분석하도록 함으로써 후자를 달성할 수 있다고 생각합니다.
이러한 모든 솔루션은 서투른 것처럼 보이므로 두 가지 질문이 있습니다.
- 호출 수신자가 호출자의 협조 없이 호출자의 컨텍스트에 지역 변수를 할당할 수 있습니까?
즉, 다음과 같이 압축할 수 있습니다.
write_local_var_assignments variable_name; eval "$variable_name"
지금 바로 입장하세요
run_local_var_assignments
?
- 함수 호출자의 이름을 얻는 더 좋은 방법이 있습니까? 파싱이나 명령어 대체 없이 바로 결과를 얻을 수 있으면 좋을 것 같습니다.
답변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
용 변수 입니다 .$a
g
typeset
이는 in을 사용하여 선언된 변수, 구문()을 사용하여 선언된 함수 또는 in을 사용하여 선언된 변수 와는 대조적입니다 . 여기서 다음을 얻습니다.ksh
function f { ...; }
ksh93
private
zsh
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는 명령으로 실행된 평가를 실행합니다.
이 함수에 의해 수행되는 이중 평가 및 %q 이스케이프는 호출자에게 개행 및 기타 특수 문자를 올바르게 전달하는 데 필요하기 때문에 존재합니다.
그러면 함수는 다음과 같이 작성할 수 있습니다.
run_local_var_assignments () {
local assignments=()
assignments+=( 'local myvar1="my value1"' )
assignments+=( 'local myvar2="my value2"' )
emit "${assignments[@]}"
}
할당은 마치 소스코드인 것처럼 작성하기 때문에 위에서 언급한 것처럼 값에 공백 같은 것들은 인용이 필요합니다.
이 답변의 상단과 같이 명령 대체에서 이 함수를 호출하면 호출자의 범위에 이러한 값과 함께 이러한 지역 변수가 생성됩니다.
명령문 배열 대신 일반 문자열이나 구분 기호를 사용할 수도 있지만 명령문 블록을 동적으로 구성하는 데 배열 접근 방식이 유용한 경우가 많기 때문에 좀 더 복잡하더라도 이를 보여주고 싶다고 생각했습니다.