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의 답변더 좋고 안전합니다.