2009-11-07 4 views
10

의 내가 변수의 이름이 다른 변수에 저장되어 있다고 가정 해 봅시다 :조회 쉘 변수, 간접적으로

myvar=123 
varname=myvar 

지금, 난 그냥 $의 변수 varName 변수를 사용하여 123을 좀하고 싶습니다. 직접적인 방법이 있습니까? 그래서이 함께했다, 이름으로 조회에 내장 그런 떠들썩한 파티를 찾을 수 없습니다 :

function var { v="\$$1"; eval "echo "$v; } 

그래서 결국 나쁘지 보이지 않는,하지만 난 경우 궁금하네요

var $varname # gives 123 

더 명백한 것을 놓쳤습니다. 미리 감사드립니다! man page of bash 가입일

+0

6 년 후에 묻는 질문과 중복되는 것으로 표시되어 있습니까? 또한 IMHO이 질문 + 답변은 연결된 것들보다 명확합니다. – inger

답변

12

:

${!varname} 

파라미터의 첫번째 문자 느낌표 인 경우는 변수 간접의 레벨이 도입된다. Bash는 나머지 매개 변수에서 형성된 변수의 값을 변수의 이름으로 사용합니다. 이 변수가 확장되면 그 값은 매개 변수 값이 아닌 의 나머지 부분에 사용됩니다. 간접 확장이라고하는 입니다.

+0

물론, 그게 전부입니다. RTFM을 시도했지만 어떻게 든이 설명 : ----------------- $ {! prefix *} $ {! prefix @} 접두어와 일치하는 이름. 이름이 prefix로 시작하고 IFS 특수 변수의 첫 번째 문자로 구분 된 변수의 이름으로 확장됩니다. @를 사용하고 확장을 큰 따옴표로 표시하면 각 변수 이름이 별도의 단어로 확장됩니다. ----------------- 명백한 대답으로 나를 공격하지 않았습니다. 건배! – inger

+0

@ DigitalRoss : 질문에 "bash"라는 태그가 붙어있어서 왜 대답을 posix 표준으로 제한하고 싶습니까? – tangens

+1

괜찮습니다. 예. bash에 적용됩니다. 완벽한 해결책은'$ {! varname}'을 발표 한 다음 가능한 문제에서 OP를 유지하기 위해 이식성 문제를 기록하는 것입니다. – DigitalRoss

12

직접 Posix를 따르는 구문은 없으며 bash ism입니다.

eval t="\$$varname" 

bash은 로그인 쉘과 /bin/sh가 더 작고 더 빠른 같은 ash 뭔가가 이러한 시스템을 포함한 모든 POSIX 및에서 작동합니다 : 난 보통 이렇게. 나는 bash를 좋아하고 나의 로그인 쉘을 위해 그것을 사용하지만 명령 파일에서 bashisms를 피한다.


주 : bash 특정 스크립트를 작성하는 데있어서 한 가지 문제점은 설치중인 bash를 믿을지라도 경로의 어느 곳에서나있을 수 있다는 것입니다. 이 경우 완전히 일반적인 /usr/bin/envshebang 스타일을 사용하는 것이 좋지만 100 % 이식성이 아니며 보안 문제가 있음을 유의하십시오.

+0

값이 필요한 컨텍스트에 따라, 할당보다는'$ (eval \ $$ varname)'을 사용할 수 있습니다. –

+0

거의 시도했지만 놓쳤습니다. 저것을위한 나의 건배보다는 더 짧은 것! – inger

+0

은'$ (....)'가 아닌 posix입니까? '\'eval \ $$ varname' \'이 아닌가요? –

1

${!varname} 트릭 내 배쉬 기술을 씻으해야 할 때 나는 보통 Advance Bash-Scripting Guide

$ var="content" 
$ myvar=var 
$ echo ${!myvar} 
content 
+0

감사합니다, 당신의 대답은 tangens보다 잠깐 늦게 도착한 것 같습니다. 그래서 나는 그 하나를 선택했습니다 :) – inger

1

을해야한다. Indirect References

표기법에서 귀하의 질문 모양에 관한

이다 : 나는 현재이 작은 기능을 사용하고

Version < 2 
\$$var 

Version >= 2 
${!varname} 
+0

흠, 그 가이드를 빨리 훑어 보았습니다 - 분명히 너무 빨리 :) 분명히 그것을 통해 읽어야하는 것처럼 보입니다. 팁 .. 팁 주셔서 감사합니다. ! – inger

+0

그것은 내가 선택한 빠른 참조이며, 나는 그것을 man 페이지보다 자주 사용하는 경향이 있습니다. 그러나 당신이 말했듯이, 언뜻보기에는 때로는 충분하지 않습니다. –

+0

일반적으로 ABS는 거대한 소금물을 가지고 섭취해야합니다. 이 답변 자체에는 아무런 문제가 없습니다. – tripleee

0
# bmuSetIndirectVar() 
# TO DOUBLE CHECK THIS COMMENT AND DEMO 
# This function is an helper to read indirect variables. 
# i.e. get the content of a variable whose name is saved 
# within an other variable. Like: 
# MYDIR="/tmp" 
# WHICHDIR="MYDIR" 
#  bmuSetIndirectVar "WHICHDIR" "$MYDIR" 
# 
bmuSetIndirectVar(){ 
    tmpVarName=$1 
    locVarName=$1 
    extVarName=$2 
    #echo "debug Ind Input >$1< >$2<" 
    eval tmpVarName=\$$extVarName 
    #echo "debug Ind Output >$tmpVarName< >$extVarName<" 
    export $locVarName="${tmpVarName}" 
} 

. 나는 그것에 만족하지 않고 웹에서 다른 솔루션을 보았습니다. (내가 여기에 적어 둘 수 있다면 그렇게 할 수는 있지만) 작동하는 것 같습니다. 이 몇 줄 안에 이미 약간의 여분과 여분의 데이터가 있지만 디버깅에 도움이되었습니다.그것이 최선의 해결책이 아니다 물론 https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh

,하지만 나를 희망, 작업으로 진행했다 : 당신은 내가 그것을 사용하고 어디에 즉 장소에서 그것을보고 싶다면

확인 나는 그것을 좀 더 일반적으로 대체 할 수있다.

+0

질문하기 전에;)이 기능이 마음에 들지 않는 것은 일반적으로 나쁜 디자인을 유발하는 "평가판"을 사용한다는 것입니다. 물론 당신이 필요로하는 곳이 있습니다. 내가 좋아하는 것은 함수를 사용하여 문제의 코드를 분리하고 나중에 최적화 할 수 있다는 것입니다. 어쩌면 쉘 버전 검사 등을 도입 할 수도 있습니다. – mariotti

관련 문제