Python subprocess/Popen with a modified environment Python subprocess/Popen with a modified environment python python

Python subprocess/Popen with a modified environment

I think os.environ.copy() is better if you don't intend to modify the os.environ for the current process:

import subprocess, osmy_env = os.environ.copy()my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]subprocess.Popen(my_command, env=my_env)

That depends on what the issue is. If it's to clone and modify the environment one solution could be:

subprocess.Popen(my_command, env=dict(os.environ, PATH="path"))

But that somewhat depends on that the replaced variables are valid python identifiers, which they most often are (how often do you run into environment variable names that are not alphanumeric+underscore or variables that starts with a number?).

Otherwise you'll could write something like:

subprocess.Popen(my_command, env=dict(os.environ,                                       **{"Not valid python name":"value"}))

In the very odd case (how often do you use control codes or non-ascii characters in environment variable names?) that the keys of the environment are bytes you can't (on python3) even use that construct.

As you can see the techniques (especially the first) used here benefits on the keys of the environment normally is valid python identifiers, and also known in advance (at coding time), the second approach has issues. In cases where that isn't the case you should probably look for another approach.

With Python 3.5 you could do it this way:

import osimport subprocessmy_env = {**os.environ, 'PATH': '/usr/sbin:/sbin:' + os.environ['PATH']}subprocess.Popen(my_command, env=my_env)

Here we end up with a copy of os.environ and overridden PATH value.

It was made possible by PEP 448 (Additional Unpacking Generalizations).

Another example. If you have a default environment (i.e. os.environ), and a dict you want to override defaults with, you can express it like this:

my_env = {**os.environ, **dict_with_env_variables}