简体   繁体   中英

Export environment variables from child bash script in GNU Make

I have a script "set_env.py" that outputs the following uppon execution:

export MY_VAR_1=some_value
export MY_VAR_2=some_other_value

I cannot change this script, it is supplied in my current environment.

Further I have a Makefile that looks like this:

SHELL := /bin/bash

all: set_env
    env | grep MY_VAR    

set_env:
    eval ./set_env.py

With this makefile I expected the grep to list my two variables, however it seems the environment is not set.

I suspect this is because make creates a sub-environment for each line and so the variables set on the first line will not be available in the second.

So the question is, how would I go about exporting the environment from the untouchable script in my makefile ?

Actually, the output of the python is valid make . One option then is to read the output of the python directly into the makefile. The only fly in the ointment is that $(shell) doesn't cut the mustard.

include Environment.mk

PHONY: test
test:
    env | grep MY_VAR

Environment.mk:
    ./set_env.py >$@-tmp
    mv $@-tmp $@

How does this work? The first thing that make tries to do is to ensure the makefile itself is up-to-date. Since we have told it to include Environment.mk , make must ensure that is up-to-date too.

  • Make finds a rule for Environment.mk
  • The python is run, creating Environment.mk
  • Environment.mk is read in, creating two make variables with the export attribute
  • The makefile is now up-to-date, so make proceeds on to the target ( test in this case)
  • Make runs test 's recipe, exporting any variables with the export attribute.

No recursion, but you should ensure the python always spits out make compatible syntax.

Recursive make is your friend I'm afraid.

.PHONY: all
all:
    eval $$(./set_env.py) && ${MAKE} test

.PHONY: test
test:
    env | grep MY_VAR    

There are a few moving parts here.

  • make all executes the shell command eval $(./set_env.py) && make test
  • The shell first does the command substitution
    • $(./set_env.py) is replaced by the export commands
  • The export commands are passed to the (shell) eval command
    • The environment variables are defined, but only for this shell invocation
  • The eval succeeds, so the execution passes to the command after the &&
  • Make runs recursively, but this second make has an augmented environment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM