[unix] 다른 변수를 “내부”로 변수 참조 사용

나는 그것이 비교적 간단하다고 확신합니다. 그냥하는 방법을 모르겠습니다.

#!/usr/bin/ksh
set `iostat`
myvar=6

나는 -> -> echo ${$myvar}로 해석하고 싶은 것을 원합니다.${$myvar}${6}value



답변

당신은이 작업을 수행 할 수 있습니다 eval, 내장 ksh를 포함하여 많은 훌륭한 쉘에 :

#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"

트릭은 eval$ myvar가 “6”으로 대체되도록 문자열을 큰 따옴표로 묶고 외부 달러 기호를 백 슬래시하여 eval문자열 “$ 6” 을 얻는 것입니다.

출력에 “% user”가 있지만 다중 프로세서 RHEL 시스템에서 시도했습니다.


답변

간접 변수 참조

현대의 고급 쉘에는 다른 변수에 이름이 저장된 변수의 값을 참조하는 방법이 있습니다. 불행히도이 방법은 ksh, bash 및 zsh간에 다릅니다.

mksh ≥R39b에서 nameref를 만들 수 있습니다 myvar:

typeset -n myvar=6
echo "$myvar"

위치 매개 변수에 대한 이름 참조를 지원하지 않기 때문에 ATT ksh93에서는 작동하지 않습니다. 변수 이름이 포함 된 변수가있는 경우이 방법을 사용할 수 있습니다.

foo=bar
typeset -n myvar=foo
echo "$myvar"  # prints bar

bash ≥2.0에서는 다음과 같이 쓸 수 있습니다.

echo "${!myvar}"

zsh에서는 다음을 작성할 수 있습니다.

echo ${(P)myvar}

다른 변수의 이름을 포함하는 변수가이 변수의 값을 사용하고자 할 때 ksh88과 pdksh 같은, 당신의 유일한 수단을 포함하여 오래된 포탄에서 eval, 브루스 Ediger에 의해 설명 된 바와 같이 . 이 솔루션은 모든 Bourne / POSIX 셸에서 작동합니다.

eval "value=\${$myvar}"
echo "$value"

배열 사용

이것이 가장 좋은 방법입니다. 더 간단하고 휴대하기 쉽습니다.

유스 케이스의 경우 배열이있는 모든 쉘 (모든 ksh 변형, bash ≥2.0, zsh)에서 배열 변수를 할당하고 원하는 요소를 사용할 수 있습니다. ksh 및 bash 배열의 번호는 0부터 시작하지만 z setopt ksh_arrays또는 1을 발행하지 않으면 zsh는 1부터 시작합니다 emulate ksh.

set -A iostat -- $(iostat)
echo "${iostat[5]}"

위치 매개 변수를 배열 변수에 복사하려면 다음을 수행하십시오 a.

set -A a -- "$@"

ksh93, mksh ≥R39b, bash ≥2.0 및 zsh에서 배열 할당 구문을 사용할 수 있습니다.

iostat=($(iostat))
echo "${iostat[5]}"


답변

Gilles ( bash대답 의 일부 를 제공 한 사람 )가 Bruce Ediger를 무효화하지 않는 방법 (으로 이식 할 수있는 방법 eval) nameref은 최근 mksh(및 @Gilles가 언급 한 것처럼 AT & T ksh93을 사용하는 방법)-namerefs AT & T ksh에서 위치 매개 변수를 참조 할 수 없으며 명명 된 매개 변수 만 참조하십시오.

#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar

저항력 향상 --set위해 후자를 추가했습니다 .


답변

배열의 또 다른 사용

ksh 또는 변형을 한동안 사용하지 않았으므로 ksh (또는 bash)에 비슷한 기능이 있는지 확실하지 않습니다. 내 기본 쉘은 zsh입니다. iostat 와 같은 명령의 출력을 처리 할 때 배열을 사용합니다. 여러 줄을 생성하기 때문에 모든 줄이 같은 형식 / 길이는 아닙니다.

#! /bin/zsh
IOStatOutput=("${(@f)$(iostat)}") # Produces one element per line

위의 방법은 위치 매개 변수를 사용하지 않습니다. 예를 들어 장치 배열을 생성하려면 다음을 수행하십시오.

for Element in {7..${#IOStatOutput}} # Devices listed in elements 7 thru the last
do
    DevList+=( ${${=IOStatOutput[Element]}[1]} )
done

작은 덩어리를 다루기가 훨씬 쉽습니다. 코드에 따라 간접 변수 참조를 사용해야 할 수도 있고 필요하지 않을 수도 있습니다. 그것이 어떻게 작동하는지 아는 것은 여전히 ​​알아 두는 것이 좋습니다. 나는 그것을 직접 사용합니다.


답변