このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

シェル(bash)のfor文の違いを吸収するMakefileの書き方

GNU bashにもいろいろなバージョンがあります。最新は 3.2.* らしいです。1.14.* なんて古いのもまだ使えます。さて、次のfor文はシェルのバージョンにより挙動が違います。

$ for x in ; do echo $x; done

GNU bash, version 3.00.15(1)-release (i686-redhat-linux-gnu) だと何も実行されませんが、エラーでもありません。GNU bash, version 2.04.0(1)-release (i686-pc-msys) だと、次のエラーになります。

sh: syntax error near unexpected token `;'

この違いはMakefileを書くときも問題になります。

dothis:
	for x in $(LIST); do\
	 echo "$$x";\
	done 

のように書いておくと、Make変数LISTが空のとき、特定バージョンのシェルはエラーしてしまいます。それで僕は、しょうがなく次のような書き方をしていました。

dothis:
	for x in dummy $(LIST); do\
	 if [ "$$x" != "dummy" ]; then\
	  echo "$$x";\
	 fi;\
	done 

これでなんとかなりますが、格好悪すぎ。

ある日気がつきました。「待てよ、LISTがシェル変数ならいいんだよな。」

$ LIST=; for x in $LIST; do echo $x; done

これならバージョンに関わらずOKです(すべてのバージョンに関しては保証しません)。ただし、変数LISTの値が空でないときは引用符が必要です。

$ LIST="a b c"; for x in $LIST; do echo $x; done

これをMakefileに書くなら:

dothis:
	LIST="$(LIST)";\
	for x in $$LIST; do\
	 echo "$$x";\
	done

こっちのほうがスッキリ。

実際に使うときは、エコーされないように、コマンドの前にアットマークを付けておきましょうね。

dothis:
	@LIST="$(LIST)";\
	for x in $$LIST; do\
	 echo "$$x";\
	done