고쳐 쓰다

고쳐 쓰다

죄송합니다. 너무 혼란스럽습니다. (안타깝습니다.)
더 간단한 예를 들어 다시 설명하겠습니다.

#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

제한 요인:

  1. VAR_ONE의 값은 변경될 수 있으므로 새로 생성된 변수를 처리하는 데 사용할 수 없습니다.
  2. 정적 이름으로는 새 변수를 선언할 수 없습니다. 사용하려면 스크립트에서 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_VARANOTHER_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. 이렇게 하면 개행 문자도 추가됩니다.

관련 정보