죄송합니다. 너무 혼란스럽습니다. (안타깝습니다.)
더 간단한 예를 들어 다시 설명하겠습니다.
#define a new var and export it to the "env":
export VAR_ONE=thisIsVarOne
# check if it was created:
env | grep VAR_ONE #this displays: "VAR_ONE=thisIsVarOne"
# use it in a simple echo command:
echo VAR_ONE=$VAR_ONE #this displays: "VAR_ONE=thisIsVarOne"
# create a new var with the name that contains the value of VAR_ONE ("newvarthisIsVarOne") in its name:
export newvar${VAR_ONE}="somePrefix${VAR_ONE}"
# verify if it has been created:
env | grep newvar # this displays: "newvarthisIsVarOne=somePrefixthisIsVarOne"
이제 내 질문은 다음과 같습니다.
이 새로운 복합 변수를 어떻게 사용합니까?
참고:
env | grep newvar
다음 이름의 파일이 있음을 나타냅니다.newvar${VAR_ONE}
하지만 나는 못해주소echo 명령과 같은 새로운 변수. 나는 시도했지만
echo ${newvar${VAR_ONE}}
이것이 나에게 주었다bash: ${newvar${VAR_ONE}}: bad substitution
제한 요인:
- VAR_ONE의 값은 변경될 수 있으므로 새로 생성된 변수를 처리하는 데 사용할 수 없습니다.
- 정적 이름으로는 새 변수를 선언할 수 없습니다. 사용하려면 스크립트에서
VAR_ONE
새로 생성된 변수 이름의 일부로 키워드가 필요합니다. 변수 이름은 다음과 같아야 합니다.newvar${VAR_ONE}
미리 감사드립니다.
답변1
설정:
export VAR_ONE=thisIsVarOne
당신은 bash 4.3+
그것을 사용할 수 있습니다 nameref
( declare -n
):
$ declare -n _var="newvar${VAR_ONE}" # nameref; define new var name and associate with nameref variable '_var' (can be any valid variable name)
$ _var="somePrefix${VAR_ONE}" # assign value to nameref
$ echo "${!_var}" # show nameref association
newvarthisIsVarOne
$ echo "${_var}" # show value
somePrefixthisIsVarOne
$ echo "${newvarthisIsVarOne}" # explicitly reference new variable by name
somePrefixthisIsVarOne
답변2
설정:
export VAR_ONE=thisIsVarOne
연관 배열을 사용하는 대안:
$ unset newvar
$ declare -A newvar
$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )
$ echo "${newvar[${VAR_ONE}]}"
somePrefixthisIsVarOne
의견에서 OP는 및 같은 여러 변수를 참조해야 함을 지적 했습니다 newvar${VAR_ONE}
.newvar${OTHER_VAR}
newvar${ANOTHER_VAR}
VAR_ONE
연관 배열을 사용하는 이 접근 방식은 3개의 변수( , OTHER_VAR
및 ANOTHER_VAR
)가 서로 다른 값을 갖는 한 작동합니다.가치그렇지 않으면 중복된 값으로 인해 단일 배열 항목이 생성됩니다(최신 할당이 이전 할당을 덮어씁니다).
이 3개의 변수가 동일할 수 있는 경우값또 다른 방법은 리터럴을 연관 배열의 인덱스로 사용하는 것입니다. 예를 들면 다음과 같습니다.
#### instead of:
$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )
#### we use:
$ newvar[VAR_ONE]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([VAR_ONE]="somePrefixthisIsVarOne" )
답변3
$
bash의 변수에 영향을 주기 위해 a를 사용하지 마세요 :
var_name=value
var_name1="value with spaces"
var_name2='value with $ or special characters'
변수의 값을 얻으려면 $
이름 앞에 a를 사용하십시오.
echo "var_name=$var_name"
echo "var_name1=use_braces_to_protect_the variable_name_${var_name1}_"
my_new_var="$var_name2"
변수에 다른 변수의 이름이 포함되어 있는 경우 변수 이름 앞에 느낌표를 붙이고 중괄호 안에 넣어야 합니다.
my_var=spam
the_var_name=my_var
echo "the value is '${!the_var_name}'"
따라서 귀하의 프로그램은 다음과 같습니다.
#! /bin/bash
VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)
echo "VAR_NAMES=" "${VAR_NAMES[@]}"
for VAR_NAME in "${VAR_NAMES[@]}"; do
echo
echo "VAR_NAME=$VAR_NAME"
NEW_VAR_NAME="newvar$VAR_NAME"
echo "NEW_VAR_NAME=$NEW_VAR_NAME"
export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"
done
고쳐 쓰다
새로운 var_name/var_value를 키/값으로 사용하여 해시 테이블(연관 배열)을 생성할 수도 있습니다.
#! /bin/bash
VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)
echo "VAR_NAMES=" "${VAR_NAMES[@]}"
declare -A NEW_VAR_NAMES=()
for VAR_NAME in "${VAR_NAMES[@]}"; do
echo
echo "VAR_NAME=$VAR_NAME"
NEW_VAR_NAME="newvar$VAR_NAME"
echo "NEW_VAR_NAME=$NEW_VAR_NAME"
export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"
NEW_VAR_NAMES+=(["${NEW_VAR_NAME}"]=${!NEW_VAR_NAME})
done
echo
echo "${NEW_VAR_NAMES[@]@A}"
for new_var_name in "${!NEW_VAR_NAMES[@]}"; do
echo "new_var_name is ${new_var_name} and its content is '${NEW_VAR_NAMES[$new_var_name]}'"
done
답변4
방문하다껍데기별도의 변수( ${!pointer}
구문 또는 이름 참조용)를 사용하는 대신 변수를 사용하는 유일한 해결책은 를 사용하는 eval
것입니다.
eval "echo \$newvar$VAR_ONE"
— 하지만 실수를 하면 위험하며 사실상 모든 인간이 실수를 합니다.
하지만~을 위한환경바꾸다일단 생성되면 export
하위 프로세스를 사용하여 조회를 수행할 수 있습니다. 특히 awk
일반적으로 나타나는 POSIX는최대시스템에는 다음이 포함됩니다 bash
.
awk -v name=newvar$VAR_ONE 'BEGIN{printf "%s",ENVIRON[name]}'
# or simpler {print ENVIRON[name]} adds newline which may be okay,
# e.g. if you use this in $(...) or `...` which removes newline
# or _instead of_ an echo command because echo also adds newline
훨씬 더 간단하고 많은 시스템이 있으며 printenv
이를 수행할 수 있습니다 printenv newvar$VAR_ONE
. 이렇게 하면 개행 문자도 추가됩니다.