Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
I don't understand the question: you seem to already have found a way to “run program with environment set to variables in a file”. Is the question how to do that from inside the Python script, so that you can directly run /path/to/myscript.py? –  Gilles Jul 23 at 23:18

3 Answers 3

up vote 3 down vote accepted

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.

share|improve this answer

You can do it all in Python:

$ cat config.py
env = {
    'FOO' : 'bar',
    'X'   : '12',
}

$ cat test.py
import os
import config

os.environ.clear()
os.environ.update(config.env)
print os.environ

Then:

$ python test.py
{'X': '12', 'FOO': 'bar'}
share|improve this answer

Another way would be to read the file into an array, and then use the array as an argument. The advantage compared to using process substitution is that it can handle values with whitespace in them. Example:

$ cat file
FOO=bar
X=12
var=a b c

$ IFS=$'\n' read -d '' -ra vars < file
$ env -i "${vars[@]}" python env.py
{'var': 'a b c', 'X': '12', 'FOO': 'bar'}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.