8

In bash, I can do this:

for name in sqls/*.{schema,migration}.sql; do
    echo $name; # some operation on the file name
done

It would output something like this:

sqls/0001.schema.sql
sqls/0002.schema.sql
sqls/0003.migration.sql
sqls/0004.schema.sql
sqls/0006.schema.sql
sqls/0007.schema.sql

However, if I put the same loop into a Makefile:

names:
    for name in sqls/*.{schema,migration}.sql; do echo $name; done

The output become:

sqls/*.{schema,migration}.sql

How can I do the same thing in a Makefile?

1
  • 3
    Could you edit your question to show exactly what you tried in your Makefile? Feb 23, 2017 at 9:38

2 Answers 2

18

What you want is :

names:
    for name in sqls/*.{schema,migration}.sql; do\
        echo $${name};\ # some operation on the file name
    done

As explained in the docs, that's the difference between accessing GNUMake and bash variables. Here's a simple example using both :

LIST = one two three
all:
        for i in $(LIST); do \
            echo $$i; \
        done

Here i is a bash variable, whilst LIST is a GNUMake variable.

In short, if you need bash to recieve a dollar sign $, put a double dollar sign $$ in your makefile. (Note that the use of {} or () is equivalent in makefiles or bash.)

4

You need to realize that the {...} is a bash construct whilst Makefiles generally launch the sh which does not support the brace expansion feature.

However all's not lost; if you are with GNU Make then you can tell Make to use bash by putting this little line SHELL := bash at the very top of your Makefile.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .