Bash 스크립트는 변수 내의 변수를 해석하지 않습니다.

Bash 스크립트는 변수 내의 변수를 해석하지 않습니다.

bash 스크립트에서 사용할 수 있도록 구성 파일에 설정된 경로를 추출해야 합니다. 경로는 해당 파일 내에서 다음과 같습니다.

DIR = "${HOME}/test/tmp"

따옴표 없이 추출해야 하는데 다음과 같이 합니다.

TESTVAR="$(cat /home/user/path/to/file.conf | grep ^DIR | grep -o '".*"' | tr -d '"')"

문제는 명령이 ${HOME} 변수를 "올바르게" 해석하지 않는다는 것입니다. 내가 전화했다고 가정해 보겠습니다 echo $TESTVAR. 결과는 다음과 같습니다.

/home/user/test/tmp

알겠어요:

${HOME}/test/tmp

따라서 스크립트 내의 명령에 대한 인수로 사용할 수 없습니다!

아름답나요?

답변1

확장은 재귀적으로 적용되지 않습니다. 그렇게 하면 달러 기호가 포함된 임의의 데이터가 처리되지 않습니다. (관련 문제는 따옴표와 리디렉션 및 기타 연산자도 확장된 일반 문자라는 것입니다.)

가장 일반적인 습관 중 하나는 이와 같은 구성 파일을 실제 쉘 스크립트로 사용하는 것입니다. 따라서 (Debian에서와 같이 /etc/default) 파일은 다음과 같습니다.

DIR="${HOME}/test/tmp"

당신은 그것을 읽을 것입니다

. configfile

물론 여기에는 문제가 있습니다. 즉, 파일이 완전한 쉘 스크립트이고 쉘 구문을 준수해야 하며 임의의 명령을 실행하도록 구성되어야 한다는 것입니다.

또 다른 가능성은 파일을 실행하는 것입니다 envsubst. 예를 들어 질문에 있는 파일을 사용하면 envsubst < configfile다음과 같이 출력됩니다.

DIR = "/home/me/test/tmp"

또는 특정 항목을 확장하는 데 사용할 수도 있습니다 envsubst '$HOME $OTHER $VARS'.

쉘 스크립트와 달리 envsubst입력 파일에서 할당을 읽지 않습니다. 예를 들어 ROOTPATH두 번째 줄에 사용된 값은 envsubst환경에서 얻은 값으로 첫 번째 줄의 "할당"과 관련이 없습니다.

ROOTPATH=/something/$USER
LOGPATH=$ROOTPATH/logs

답변2

이것은 당신이 원하는 것을 얻는 불필요하게 복잡한 방법입니다! 필요한 것은 다음과 같습니다(변수 이름도 소문자로 변경했습니다. 쉘 스크립트 변수는 이름 충돌을 일으킬 수 있는 환경 변수에 사용되므로 대문자를 사용하지 마십시오).

testvar="$(grep -oP '^DIR\s*=\s*"\K[^"]+' /home/user/path/to/file.conf)"

이것은 당신을 얻을 것입니다 testvar=${HOME}/test/tmp. 확장하려면 $HOME이제 평가해야 합니다.

testvar=$(eval echo "$testvar")

그러나 eval임의의 코드에 사용하는 것은 매우 위험합니다. 읽고 있는 파일에 명령이 포함되어 있으면 해당 명령이 실행됩니다. 그래서 주어진 방법은@ilkkachu의 답변더 좋고 안전합니다.

관련 정보