Makefile内でのbash拡張グロブ


14

特定のプレフィックス(たとえばexclude_)で始まらない特定のフォルダー内のすべてのファイルに対して操作を行いたい。for次のような拡張グロブを持つbash ループがあります。

for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done

コマンドラインでは、これは正常に機能します。

 $ for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
 foo/bar/apple
 foo/bar/pear
 foo/bar/banana

ただし、メイクファイルで使用する場合:

target:
    for FILE in foo/bar/!(exclude_*) ; do echo $$FILE ; done

次のエラーが表示されます。

$ make
for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done'

逃した必要なエスケープがありますか?

回答:


6
  1. 設定する必要がありますextglob
  2. makeにshではなくbashを使用するように指示する必要があります。

メイクファイル:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...

2
うーん。何らかの理由.SHELLFLAGSで私にとってはうまくいきませんでしたが、フラグを直接入れるとSHELL=/bin/bash -O extglob -cうまくいきました。なぜアイデアがありますか?
ティモシージョーンズ

1
たぶん、GNU makeを使用していないのでしょう。または、引用符は必要ありません。
イグナシオバスケス-エイブラムス

GNU Make 3.81、およびGNU bash、バージョン4.1.2。引用符も付けずに試しました。奇妙な。
ティモシージョーンズ

とにかく、すべてを1行にまとめると、あなたの答えで解決しました。ありがとう!
ティモシージョーンズ

1
この.SHELLFLAGS変数はGNU make 3.82で追加されました。NEWSファイルを使用して、どのリリースにどの機能が追加されたかを確認できます:git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

10

これをBashハックではなく、Makeで解決する方が、より慣用的でより移植性があります。誰かがBashをインストールしていない場合はどうなりますか?

とにかく、Makeでそれを行う適切な方法を次に示します

FOOFILES = $(filter-out foo/bar/exclude_%,$(wildcard foo/bar/*))

target:
    for FILE in ${FOOFILES}; do echo $$FILE ; done

2

より簡単な方法を次に示します。

SHELL:=/bin/bash -O globstar

これにより、globstarシェルオプションが有効になります(BSD / OS Xでも動作します)。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.