$ bash -version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
次のシェルスクリプトを考えてみます。
#!/bin/bash
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )
for key in "${!PROVS[@]}" ; do \
touch "foo_${key}_${PROVS[${key}]}" ; \
done
私はMakefileで同等のものをやろうとしています:
Shell := /bin/bash
.PHONY: foo
foo:
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )
for key in "$${!PROVS[@]}" ; do \
touch "foo_$${key}_$${PROVS[$${key}]}" ; \
done
ファイルをtouch
したくありません本当に; @echo
を実行できないため、これを行っています。ループにいるため、@が行の先頭にあるとは見なされません。またはそれが起こっているようです。
とにかく、ポイントは、ループがまったく実行されていないように見えるため、touch
/echo
ビジネスです。上記のシェルスクリプトの内容は、make
がターミナルにエコーするものとまったく同じです。私はシバンを追加して、それを健全性チェックとして実行しました-魅力のように機能します。
通常の配列を使用するとうまくいきます:
for prov in NL PE NS NB QC ON MB SK AB BC YK NT NU ; do \
ただし、これらのコード(10、11など)も必要です。
誰かこれについて洞察がありますか?
必須ではありませんが、「declare -A」を使用しながら、ファイルの先頭にPROVS変数を割り当てる方法(または可能であれば)も知りたいです。
編集:インラインシェルコマンドの一部にすぎないようにMakefileの例を台無しにしたので、もはやレシピではありません。明確にするために、「foo:」ターゲットを再度追加しました。
コードの抜粋が適切に表現されている場合、Makefileに直接Bashコマンドを入力しており、MakeがBashでそれらを実行することを期待しているようです。それはそれがどのように機能するかではありません。 Makefileの構文は完全に異なります。 レシピ内で、Bashコマンドを入力できます。レシピの個別の各行は、個別のサブシェルで実行されます。したがって、少なくとも2つの変更が必要です。
declare
はループと同じシェルで実行する必要があります。それ以外の場合は、1つのBashインスタンスでdeclare
を実行し、それを終了してから、失われたdeclare
について何も認識していない別のインスタンスでループを実行します。以下は、これらの変更を加えたMakefileの簡単なリファクタリングです。
Shell=/bin/bash # This is the standard compliant method
.PHONY: all
all:
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 \
["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 \
["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )\
; for key in "$${!PROVS[@]}" ; do \
touch "foo_$${key}_$${PROVS[$${key}]}" ; \
done
コマンドをサイレントに実行するための@
規則は、コマンドライン全体に適用されます。したがって、上のdeclare
の前に置くことができます。その場合、コマンドライン全体がBashに送信される前に削除されます。それ以外の場所では、それは取り除かれたり理解されたりせず、呼び出されたシェルで明らかにBash構文エラーを引き起こします。
(@
ルールへの執着はとにかく反パターンです。出力を表示したくない場合はmake -s
で実行してください。make
をシャットダウンするとデバッグが難しくなりますあなたのルール。)