Bash – Run Program with Environment Variables from File

bashenvironment-variables

I would like to run a program (in this case Python) with only the environment variables defined in a file, say vars.env:

FOO=bar
X=12

Here's a simply Python script that prints the environment:

import os
print os.environ

If I run env -i python script.py, os.environ is empty as expected. Likewise, if I run

$ env -i FOO=bar X=12 python env.py

I get

env: {'X': '12', 'FOO': 'bar'}

However what I would like to do is load the environment from my vars.env file when running the script. How can I accomplish this?

EDIT: One thing that I could do is cat this env file, like env -i `cat vars.env` python env.py but I would prefer to be able to source it in some way.

Best Answer

Given the file you show, you should be able to do:

(set -f ; IFS='
' ; env - $(cat /path/to/file) /path/to/your/program
)

If it doesn't work then it is only because you need to format your environment file first. Here's an example:

(set -f ; IFS='
' ; env - $(cat) printenv 
) <<\ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
ENV
###OUTPUT###
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore

I at first thought you could do it through the shell - but it will probably set some of its own environment before calling your program. But I can at least demonstrate that the arguments are assigned correctly:

(set -f; IFS='
' ; env - $(cat) sh -c 'echo "$variable3"'
) <<\ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
ENV
###OUTPUT###
value3 an$d s'om\e m"ore

Still, if you would prefer to source it, here's how you can using the shell:

(echo '$1'; cat; echo '$2') <<\ENV |\
env - sh -s -- 'set -a' printenv
variable1=value1
variable2=value2
variable3='value3 an$d s'\''om\e m"ore'
ENV
###OUTPUT###
PWD=/home/mikeserv/test
SHLVL=1
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
_=/usr/bin/printenv

Notice that I removed the $IFS stuff - that's not necessary this way - but I did have to get specific about the quotes in the file. Here I'm essentially .dot sourcing stdin - reading the |pipe as input - but you can use any file. I use set -a before reading the input file to set the --allexport option.

That is a result of using bash's sh - it adds $PWD, $SHLVL and $_. With dash it is a little better. And dash doesn't add a bunch of exports either, so you can specify the -a parameter on the command line:

(cat; echo '$1') <<\ENV |\
env - dash -sa -- printenv 
variable1=value1
variable2=value2
variable3='value3 an$d s'\''om\e m"ore'
ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
PWD=/home/mikeserv/test

Only $PWD comes through.

Related Question