将路径传递给“。”生成文件中的源代码

Pass a path to the "." source in a makefile

在一个目录中,我有一个包含我的数据库变量的配置文件。

此文件 (db/database.ini) 如下所示:

[PostgreSQL]
host=localhost
database=...
user=postgres 
password=...

我有另一个文件 (db/create_stmts.sql),其中包含我所有的原始创建 table 语句,我正在尝试使用 Makefile 来执行这样的命令:

make create-db from_file=db/create_stmts.sql

为了不重复我自己,我想到了 taildb/database.ini 的变量写入一个文件,然后我将获取该文件,创建 shell 个变量以传递给 psql 在生成文件中。

这是我的计划:

make-db:

        # from_file: path to .sql file with all create statements to create the database where to insert
        # how to run: make create-db from_file={insert path to sql file}

        file_path=$(PWD)/file.sh
        tail -n4 db/database.ini  > file.sh && . $(file_path)

        # -U: --user
        # -d: --database
        # -q: --quiet
        # -f: --file
        psql -U $(user) -d $(database) -q -f $(from_file) && rm file.sh

我 运行 通过:make create-db from_file=db/create_stmts.sql

这给了我这条消息 - 我从中了解到采购根本不起作用。

#from_file: path to .sql file with all create statements to create the database where to insert
# how to run: make create-db from_file={insert path to sql file}    
file_path=/home/gabriele/Desktop/TIUK/companies-house/file.sh
tail -n4 db/database.ini  > file.sh && .    
# -U: --user
# -d: --database
# -q: --quiet
# -f: --file
psql -U  -d  -q -f db/schema_tables.sql && rm file.sh
psql: FATAL:  Peer authentication failed for user "-d"
Makefile:3: recipe for target 'create-db' failed
make: *** [create-db] Error 2

有什么帮助吗?

错误在文中,即

psql -U  -d  -q -f db/schema_tables.sql && rm file.sh

发生这种情况是因为未设置变量 $(user)$(database)。目标中的每一行都在子 shell 中执行。现在可以像在常规脚本中一样使用 source

您可以创建一个名为 database.mk 的文件,您可以在其中定义这些变量,并在 makefile 的顶部使用 include database.mk 来包含它们:

生成文件

CONFILE ?= database
include $(CONFILE).mk

test:
        @echo $(user)
        @echo $(database)

database.mk

user     := user
database := data

如果你想解析 ini 文件,你可以这样做

CONFILE := db/database.ini

make-db: _setup_con
        echo $(user) $(database)
        # your target

_setup_con:
        $(eval user=$(shell grep "user=" $(CONFILE) | grep -Eo "[^=]*$$"))
        $(eval database=$(shell grep "database=" $(CONFILE) | grep -Eo "[^=]*$$"))
        # and so forward

另一个解决方案,也许更容易理解:

make-db:
        file_path=$$PWD/file.sh; \
        tail -n4 db/database.ini  > file.sh && . $$file_path; \
        psql -U $$user -d $$database -q -f $$from_file && rm file.sh

注意使用 ;\ 说服 make 到 运行 单个 shell 中的所有命令,并使用 $$ 转义 $ 并使用 shell 变量引用。

我会通过使用自动生成 Makefile 的功能使它更 Make-way。鉴于配置文件是一个简单的属性文件,它的语法很容易被 Make 解析,只需获取带有变量的行就足够了,即:

include database.mk

database.mk: db/database.ini
        grep -E '^\w+=\w+$$' $< > $@

.PHONY: create-db
create-db: $(from_file)
        psql -U $(user) -d $(database) -q -f $<

一些补充说明:

  • create-db 应该设为 .PHONY 以避免由于某人(无意或无意)创建了名为 create-db
  • 的文件而导致什么都没做的情况
  • 通过使 create-db 依赖于 from_file 可以从 make 得到一个清晰且可读的错误,即文件不存在,而不是稍后可能出现的神秘错误。