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次拡張。
どんなアイデアがありますか?
重要であれば、これはbash4.4.12(1)-release
でmakeです。GNU Make 4.1
答え1
あなたは本当にすごいです。質問を投稿してから10分も経たないで、あなたは私に正しい解決策を案内してくれました。
# Makefile
SHELL=/bin/bash
test:
foo=bar; \
ind=foo; \
echo $${!ind}
スチールドライバー、チョロバ様、ありがとうございます。
答え2
ここには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