함수를 생성하는 함수를 만들려고 합니다. 외부 함수에 전달된 내용을 기반으로 내부 함수의 매개변수를 "하드코딩"하고 싶습니다.예를 들어
outer() {
inner() { doSomething --context=$1 $@ }
}
위의 내용을 참고하여 전화를 하시면
outer foo
내부 함수를 다음과 같이 정의하고 싶습니다.
inner() { doSomething --context=foo $@ }
즉, 내부 함수 정의에 외부 함수의 $1을 삽입하되 내부 함수 호출 시 삽입을 위해 $@를 유지합니다.
이 목표를 어떻게 달성할 수 있나요?
편집하다, 내 사용 사례가 궁금하신 분들을 위해:
하위 명령이 포함된 명령줄 도구를 사용하고 있습니다.예를 들어
doSomething dothis somearg
doSomething dothat
하지만 항상 컨텍스트 플래그가 필요합니다.예를 들어
doSomething --context foo dothis somearg
doSomething --context foo dothat
일반적으로 컨텍스트를 입력하면 다음 몇 가지 명령은 동일한 컨텍스트를 사용합니다.
따라서 이상적인 솔루션을 사용하면 컨텍스트를 한 번 설정하고 컨텍스트가 이미 알려진 별칭처럼 내부 함수를 사용할 수 있습니다.
outer foo
inner dothis somearg
inner dothat
이는 환경 변수를 통해서도 수행할 수 있습니다.예를 들어
alias inner="doSomething --context=$CONTEXT"
그러나 실제로는 1개가 아닌 2개의 플래그가 있으며 이는 (이제 현실적인 매개변수를 사용하여) -
outer gke_gke-xpn-1_europe-west1_europe-west1-s41l stats_service
inner dothis somearg
inner dothat
—— (나에게는) ——보다 사용자 친화적입니다.
CONTEXT=gke_gke-xpn-1_europe-west1_europe-west1-s41l
NAMESPACE=stats_service
inner dothis somearg
inner dothat
답변1
함수를 생성하는 함수를 만들려고 합니다. 외부 함수에 전달된 내용을 기반으로 내부 함수의 매개변수를 "하드코딩"하고 싶습니다.
당신이 원하는 것은 클로저인데 Bash에는 그런 클로저가 없다고 생각합니다.
내부 함수가 실행되는 "컨텍스트"로 다른 전역 변수를 사용하면 됩니다. 예를 들어
context=
outer() {
context=$1
}
inner() {
if [ -z "$context" ]; then
echo "context not defined" >&2
return 1;
fi
doSomething --context="$context" "$@"
}
두 개의 컨텍스트 변수가 필요한 경우 다른 변수를 추가하면 됩니다.
두 가지를 모두 인용 "$context"
하고 "$@"
공백이나 와일드카드가 포함된 값이 단어 분리로 인해 손상되지 않았는지 확인해야 합니다.
답변2
글쎄, 한 시간 동안 고민한 끝에 실제로 알아냈습니다. 핵심은 eval
보간을 지연시켜야 하는 변수를 사용하고 이스케이프하는 것입니다. 더 좋은 방법이 있다면 알고 싶습니다! 답변을 추가해 주세요.
#!/bin/bash
outer() {
eval "inner() { doSomething --context=$1 \$@ }"
}
답변3
Bash에서는 다음과 같이 수행됩니다.
#!/bin/bash
outer() {
# define inner function
inner() {
echo 1=$1 2=$2
}
# call inner function
inner $1 $2
}
# this would give an error,
inner foo 123
# call outer function.
outer bar 456
# now the inner function is defined and ready to be used by itself
inner baz 789
답변4
에서는 bash
다음과 같이 작동합니다.
outer() { . <( echo "inner() { doSomething $1 $2; }" ); }