Bash에서는 두 가지 방법으로 가변 간접 확장을 수행할 수 있다는 것을 알고 있습니다.
- 사용
declare
:declare -n foo=bar
- 확장 기능을 사용하세요
${!..}
.
우리는 두 가지를 결합할 수 있습니다:
declare -n foo=SHELL
bar=foo
echo ${!bar}
다음을 제공합니다:
/bin/bash
더 많은 수준으로 확장할 수 있나요?
대부분은 난독화된 코드를 작성하는 것에 관한 것입니다. 내 친구들 중 몇몇은 이를 하려고 서로 도전하고 있습니다.
답변1
실제로 Bash에서 간접적인 방법을 수행하는 또 다른 방법이 있습니다. 최소한 작동합니다. a=1
and 가 있는 경우 다음과 같이 through 의 값을 얻을 수 있습니다 b=a
.a
b
eval echo \${$b}
이는 여러 번 중첩될 수 있습니다.
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\\\\\${\\\${\${$d}}}
1
각 수준에서 올바른 백슬래시 수를 찾는 규칙은 다음과 같습니다.
- 가장 안쪽 수준에서는 백슬래시가 사용되지 않습니다.
- 다른 레벨에서는 2를 사용합니다.N+ 1 백슬래시, 여기서N다음 내부 수준에서 사용되는 백슬래시 수입니다.
이유: 규칙 1은 사소한 것입니다. 규칙 2는 다음 내부 레벨에서 백슬래시를 하나 더 적용해야 하고, 현재 레벨에서 소비되지 않은 모든 것, 즉 하나를 제외한 모든 것을 이스케이프해야 한다는 사실에서 비롯됩니다.
따라서 필요한 백슬래시 수는 수준 수가 증가함에 따라 기하급수적으로 증가하므로 이 접근 방식의 중첩 한계에 빠르게 도달합니다.
그러나 여기서는 이러한 제한이 매우 학문적이라는 점을 강조해야 합니다. 실제로 유지 관리 가능성과 같은 요구 사항을 존중해야 하는 경우 일반적으로 어떤 간접 방법을 사용하든 관계없이 표현식에서 2~3개 이상의 간접 참조 수준을 처리하고 싶지 않습니다.
대신 루프를 사용하여 다음과 같은 항목을 반복함으로써 더 높은 수준의 간접 참조를 해결할 수 있습니다.
value=${variable}
variable=${!value}
주어진 응용 프로그램에 대해 적절하게 여러 번.
답변2
(큰) 간접 참조의 직접 사용은 산술 확장에서만 허용됩니다.숫자.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
선언을 사용하여 확장할 수 있습니다.
$ jj=123; for ii in {a..f}{a..z}; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
그러나 그것은 무한하지 않습니다:
$ jj=123; for ii in {a..z}{a..z}; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
충분한가?