VARNAME
다른 변수의 이름을 포함하는 변수가 있습니다 . 나는 그것을 사용하지 않고 다른 변수에 할당하고 싶습니다 eval
. 어떻게 해야 하나요?
사용하고 싶지 않은 이유 eval
는 다음과 같습니다. 먼저 변수를 앞에 추가하는 함수를 가정합니다 foo
.
% prepend_foo() { foo=("$@" $foo) }
% foo=(1 2)
% print -l $foo
1
2
% prepend_foo x 'a b c' y
% print -l $foo
x
a b c
y
1
2
%
이제 변수에 첨부된 일반 함수를 생각해 보세요.
% prepend() { var=$1; shift; eval "$var=($@ ${(P)var})" }
% foo=(1 2)
% print -l $foo
1
2
% prepend foo x 'a b c' y
% print -l $foo
x
a
b
c
y
1
2
%
보시다시피 공백이 있는 변수는 여러 배열 항목으로 분할됩니다. 내가 원하는 것을 달성하기 위해 따옴표를 올바르게 결합할 수 없습니다.
IRC에서 누군가 사용을 제안했지만 ${name::=word}
이는 배열에서는 작동하지 않습니다.
21:23 < someone> > b=(bar baz); a=b; : ${(P)a::=(foo ${(P)a})}; typeset -p b
21:23 < machabot> someone: typeset b='(foo bar baz)'
21:23 < someone> dammit that's a string
답변1
배열에 요소를 추가하려면 다음을 수행할 수 있습니다.
a[1,0]=(more elements)
아니면 이렇게 할 수도 있습니다:
a=(more elements "$a[@]")
다음을 수행하십시오.
a=(more elements $a)
의 빈 요소는 제거됩니다 $a
.
이제 이를 위한 함수를 만드는 것이 목적이지만 eval
구문이 올바른지 확인해야 합니다.
prepend() {
eval "${1}[1,0]"='("${@[2,-1]}")'
}
("${@[2,-1]}")
문자 그대로 에 전달되도록 .를 작은따옴표로 묶는 방법을 확인하세요 eval
.
또는 더 긴 방법이지만 작동하지 않습니다 prepend var more elements
(변수 이름이 인 경우 var
).
prepend() {
local var=$1; shift
eval "$var"='("$@" "${'"$var"'[@]}")'
}
eval
평가하려는 코드는 prepend varname ...
다음과 같습니다.
varname=("$@" "${varname[@]")
"$@"
에 전달하기 전에 확장 하고 싶지 않습니다 eval
. $var
거기까지 확장하면 됩니다 .
변수 확장 플래그는 정리되지 않은 데이터와 함께 사용될 때 마찬가지로 위험합니다 P
.eval
var='x[$(uname>&2)0]'
echo "${(P)var}"
명령 uname
이 실행됩니다.
답변2
한 번에 하나의 요소를 이동 취소하기 위해 요소를 반복하면 prepend
함수 없이도 함수를 작성할 수 있습니다.eval
$ prepend () {
then> local i=$#*
then> while [[ $i > 1 ]]; do
then> typeset -g "${1}[1,0]=$*[$i]"
then> i=$((i - 1))
then> done
then> }
$ foo=(a 'b c' d)
$ prepend foo m 'n o p' q r
$ print -l $foo
m
n o p
q
r
a
b c
d
$
조판은 -g
로컬이 아닌 배열 요소 설정을 허용해야 하지만 이것이 참조된 배열이 $1
호출 함수에 대해 로컬일 수 없다는 의미는 아닙니다. 이는 단지 "이 배열은 함수 호출 스택을 검색하여 찾을 수 있습니다"를 의미합니다.