Search code examples
bashmakefileenvironment-variables

Why is this Makefile behavior different from bash


So I have a make file with various commands. One of the commands just runs the main python script, but before doing so it exports environment variables stored in dev.env.

The make file command to run the main python script is:

run-dev:
    # Why does this need to be one line to work???  
    set -a && source dev.env && set +a && python __main__.py

This runs just fine, both as a make command (make run-dev) and in bash (set -a && source dev.env && set +a && python __main__.py. All the environment variables are exported to the environment before the __main__.py file invocation, which loads those environment variables using os.environ.

But why does the following not work in a make file?

run-dev:
    set -a
    source dev.env
    set +a
    # Python's environment cannot see the variables from `dev.env` in `os.environ` 
    python __main__.py

Here, make run-dev fails because __main__.py can't see the environment variables? Copy-pasting those 4 lines to bash still works. Why?


Solution

  • By default, each line in a recipe is run in it's only shell, you need ONESHELL:

    .ONESHELL:
    
    run-dev:
        set -a
        source dev.env
        set +a
        # Python's environment cannot see the variables from `dev.env` in `os.environ` 
        python __main__.py