Makefile 包含 env 文件

Mic*_*win 51 make environment-variables

我正在尝试将一些环境变量包含到 Makefile 中。env 文件如下所示:

FOO=bar
BAZ=quux
Run Code Online (Sandbox Code Playgroud)

请注意,没有通向export每个 env var。如果我在 Makefile 中添加前导文件exportincludeenv 文件,则一切正常。但我需要保持 env vars sans 领先export。这使我无法仅include envfile在 Makefile 中使用。

我也试过做这样的事情:

sed '/^#/!s/^/export /' envfile > $(BUILDDIR)/env
include $(BUILDDIR)/env
Run Code Online (Sandbox Code Playgroud)

但是这样做会导致 make 抛出错误,因为 env 文件不存在。

meu*_*euh 70

如果您使用的是 gnu make,那么应该包含该envfile文件,然后导出从同一文件中获得的变量列表:

#!make
include envfile
export $(shell sed 's/=.*//' envfile)

test:
        env
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答,太棒了!尽管我的版本甚至可以在没有 `export $(shell...` 行的情况下工作。我只需要 `include` 行。 (11认同)
  • 值得注意的是,如果你在 env 文件中有任何 `$`,make 不会喜欢它们,你必须逃避它们。`PASS=Pass123$` 只会显示为 `Pass123`。这个答案很好地解释了警告。/sf/answers/3124603191/ (2认同)

小智 68

我遇到了类似的问题并登陆了这个线程。另一种可能的解决方案是不带任何参数执行 make export 命令:

include .env
export
Run Code Online (Sandbox Code Playgroud)

这会将所有 make 变量导出为环境变量。这种行为可能匹配也可能不匹配所有用例,但它对我有用并且不涉及任何 shell 脚本向导。

  • 为了更好的向后兼容性,我建议设置 `.EXPORT_ALL_VARIABLES:` 特殊目标,而不是使用 `export` 指令,如手册中所述:https://www.gnu.org/software/make/manual/ html_node/Variables_002fRecursion.html (5认同)

小智 10

要完成之前的回答meuh,如果您希望 env 文件是动态的,您可以定义一个设置函数。

  • 创建env/local-dev.env包含env/integ.env一些内容的文件
  • 定义一个方法来加载它
    定义setup_env
        $(eval ENV_FILE := env/$(1).env)
        @echo“-设置环境$(ENV_FILE)”
        $(eval包括env/$(1).env)
        $(eval export sed 's/=.*//' env/$(1).env)
    恩德夫

然后使用它

    localDevEnv: ##加载env/local-dev.env环境
        $(调用 setup_env,local-dev)
    integEnv: ##加载env/integ.env环境
        $(调用 setup_env,integ)

  • 奇迹般有效! (3认同)

小智 10

如何在 Makefile 中使用 .env 值的示例

#!make
include .env

migrateinit:
    migrate create -ext sql -dir mysql/migrations -seq int_schema

migrateup:
    migrate -path mysql/migrations -database "mysql://${DB_USER_NAME}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -verbose up 1

migratedown:
    migrate -path mysql/migrations -database "mysql://${DB_USER_NAME}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -verbose down 1
Run Code Online (Sandbox Code Playgroud)


小智 6

保留预先存在的 ENV 变量

export $(shell [ ! -n "$(ENVFILE)" ] || cat $(ENVFILE) | grep -v \
    --perl-regexp '^('$$(env | sed 's/=.*//'g | tr '\n' '|')')\=')

test:
    echo $$FOO
Run Code Online (Sandbox Code Playgroud)

跑步

make ENVFILE=envfile test # bar

export FOO=foo
make ENVFILE=envfile test # foo
Run Code Online (Sandbox Code Playgroud)


hol*_*lms 6

如果您的文件名是,.makerc那么您可以像这样简单地将它包含在 Makefile 中:

include .makerc
Run Code Online (Sandbox Code Playgroud)

我更喜欢在-之前添加符号include,以抑制任何警告。

  • 我无法在 make 4.2.1 上验证这一点。包含后无需导出。 (2认同)

mpe*_*mpe 5

这是一个优雅的解决方案,它不会导入 Make vars,但会为 shell 子进程设置任何环境导出。我个人更喜欢保留我的个人资料动态脚本。

export BASH_ENV=tools/sh/env.sh
Run Code Online (Sandbox Code Playgroud)

有一些问题。不幸的是 ENV 不起作用,我认为它应该(但这是 Bash 的问题,而不是 Make)。此外,它确实需要另一行,因为 Make 的默认 shell 解释器是 /bin/sh。

BASH_ENV := tools/sh/env.sh
SHELL := /usr/bin/bash
Run Code Online (Sandbox Code Playgroud)

从好的方面来说,这也允许在 Makefile 脚本中包含 shell 函数,但仅限于配方脚本。我不知道除了 Bash 之外的其他 shell 怎么样。还有更多的事情要做。我把一些测试文件作为 GIST

有很多可以想象的复杂的 shell 脚本。对于简单的答案,我最喜欢这个 Q/A。

  • 参考:https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Invoked-non_002dinteractively (2认同)