Bash에서는 다음을 원합니다.
- ID1, ID2, ID3이라는 변수 3개를 만듭니다.
- 변수에는 각각 문자열 값 ID1_VALUE, ID2_VALUE 및 ID3_VALUE가 할당됩니다.
이렇게 for 루프를 만들었습니다.
for ID_COUNT in 1 2 3; do
ID${ID_COUNT}=ID${ID_COUNT}_VALUE;
done;
코드 조각이 실행되면 다음과 같은 결과가 나타납니다.
ID1=ID1_VALUE: command not found
ID2=ID2_VALUE: command not found
ID3=ID3_VALUE: command not found
그리고 ID1, ID2, ID3 값은 설정되지 않습니다( set | grep ID1
아무것도 표시되지 않음).
무슨 일이 일어나고 있는지 자세히 설명해 줄 수 있는 사람이 있나요?
답변1
bash
사용된 변수를 평가하기 전에 변수 할당을 발견하는 명령줄 해석에 특별한 주의를 기울이는 것 같습니다 . 기본적으로 변수 할당에서는 이름 부분이 평가를 통해 파생된 이름이 아닌 고유 이름이어야 합니다. 그러나 "nameref"라는 개념이 있습니다. 여기서 변수는 변수 이름을 값으로 가지며, 이에 대한 할당은 해당 값의 이름을 딴 변수에 대한 할당이 됩니다. 귀하의 예에서는 다음과 유사하게 보입니다.
for ID_COUNT in 1 2 3; do
declare -n X=ID${ID_COUNT}
X=ID${ID_COUNT}_VALUE;
done;
물론 eval
호출 컨텍스트에서 해당 인수를 명령으로 평가하는 명령을 사용하여 동일한 효과를 얻을 수 있습니다. 사용하면 다음과 같습니다.
for ID_COUNT in 1 2 3; do
eval ID${ID_COUNT}=ID${ID_COUNT}_VALUE;
done;
앞에서 언급했듯이 using은 export
유사한 효과를 가지며 주요 기능인 변수를 하위 프로세스로 내보내는 기능도 제공합니다.
답변2
현재와 미래의 스크립트에 배열을 사용하면 더 좋을 것입니다.
#!/bin/bash
for i in 1 2 3; do
id[i]="ID${i}_VALUE"
done
echo 'contents of the array "id":'
printf '\t%s\n' "${id[@]}"
이 스크립트의 출력은 다음과 같습니다.
contents of the array "id":
ID1_VALUE
ID2_VALUE
ID3_VALUE
스크립트의 루프는 다음으로 대체될 수도 있습니다.
id=( "ID"{1..3}"_VALUE" )
중괄호 확장을 사용하여 배열을 만듭니다.
코드에서 일어나는 일은 변수 $ID_COUNT
의 값이 2이면 ID${ID_COUNT}=ID${ID_COUNT}_VALUE;
확장된다는 것입니다. 그러나 명령을 실행할 때 변수가 이미 감지되었으므로 이제 얻은 내용은 다음과 같습니다.ID2=ID2_VALUE
끈거기에 등호가 있습니다. 쉘은 마치 명령 이름인 것처럼 문자열을 계속 실행하려고 시도합니다.