Bash의 간접 변수 설정은 다음과 같이 수행할 수 있습니다.그래서:
#!/bin/bash
foo=bar
ind=foo
echo ${!ind} # prints `bar'
(GNU) Makefile 레시피와 동일하게 실행해 보세요.
# Makefile
test:
foo=bar
ind=foo
echo $$\{!ind\}
echo $${!ind}
문자가 이스케이프되었는지 여부에 관계없이 {}
다음 메시지와 함께 실패합니다.
foo=bar
ind=foo
echo $\{!ind\}
${!ind}
echo ${!ind}
/bin/sh: 1: Bad substitution
/tmp/Makefile:2: recipe for target 'test' failed
make: *** [test] Error 2
문제는 Makefile에서 특수 문자가 누락되거나 잘못 이스케이프되었을 수 있습니다.
또는 변수 확장의 순서/타이밍일 수도 있습니다.Make의 2차 확장.
어떤 아이디어가 있나요?
중요하다면 이것은 bash 4.4.12(1)-release
이고 make 입니다.GNU Make 4.1
답변1
너희들은 정말 대단하다. 질문을 게시한 지 10분도 채 지나지 않아 귀하는 저에게 올바른 해결책을 안내해 주셨는데, 이는 다음과 같습니다.
# Makefile
SHELL=/bin/bash
test:
foo=bar; \
ind=foo; \
echo $${!ind}
스틸드라이버님, 초로바님, 감사합니다.
답변2
여기에는 두 가지 질문이 있습니다.
- 레시피의 기본 셸은 이므로 비슷한 구문을 이해하려면 레시피를
sh
사용해야 합니다.SHELL=/bin/bash
${!ind}
- 레시피의 각 라인은 별도의 셸에 의해 실행되므로 레시피에 변수를 정의하면 동일한 레시피의 다음 라인에서 해당 변수가 손실됩니다. 이는
.ONESHELL
특별한 목표를 통해 해결 됩니다.
따라서 실제 예는 다음과 같습니다.
# Makefile
.ONESHELL:
SHELL=/bin/bash
test:
foo=bar
ind=foo
echo $$\{!ind\}
echo $${!ind}
더 자세한 (그리고 공식적인) 설명을 보려면 다음 사이트를 방문하세요. https://www.gnu.org/software/make/manual/make.html#Execution