Bash

Makefile循環文件與模式

  • February 11, 2021

在 bash 中,我可以這樣做:

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

它會輸出如下內容:

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

但是,如果我將相同的循環放入 Makefile:

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

輸出變為:

sqls/*.{schema,migration}.sql

如何在 Makefile 中做同樣的事情?

您需要意識到 {…} 是一個 bash 結構,而 Makefiles 通常會啟動不支持大括號擴展功能的 sh。

然而,一切都沒有失去;如果您使用 GNU Make,那麼您可以通過將這一行SHELL := bash放在 Makefile 的最頂部來告訴 Make 使用 bash。

你想要的是:

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

正如docs中所解釋的,這就是訪問GNUMakebash變數之間的區別。這是一個使用兩者的簡單範例:

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

i是一個 bash 變數,LIST而是一個 GNUMake 變數。

簡而言之,如果您需要 bash 來接收美元符號,請在您的 makefile 中$放置一個雙美元符號。$$(請注意,在 makefile 或 bash 中使用{}or()等效的。)

引用自:https://unix.stackexchange.com/questions/347032