13
subprocess.run('export FOO=BAR', shell=True)

This simply doesn't work, and I have no idea why.

All I am trying to do I set an environment variable from my python (3.5.1) script, and when I run the above line, nothing happens. No errors are raised, and when I check the environment variable myself, it has not been set.

Other shell commands with subprocess.run() do work, such as ls and pwd, but not export.

.run() was added in Python 3.5 (in case you didn't recognise it), but I have also tried the above line with .call() and .Popen(), with no change in results.

I am aware that I can set environment variables in python with os.environ['FOO'] = "BAR", but I will be using shell commands a lot in my project, and I expect that I will need to string multiple commands together, which will make using export easier than os.environ.

My project will run on Linux, which is what my machine is running on.

1
  • 1
    think: each subprocess.run(shell=True) starts a new shell. Open two terminals and type export FOO=BAR in one terminal and echo $FOO in another (the second terminal that runs a separate shell won't see the new $FOO value). It is the same reason why cd is a shell builtin (because it changes the working directory of the current process and if it were a separate program then cd would had to change the environment of the parent process—that can't be done (normally)). See How do I set the working directory of the parent process? Commented May 18, 2016 at 23:27

1 Answer 1

14

It works fine; however, the variable setting only exists in the subprocess. You cannot affect the environment of the local process from a child.

os.environ is the correct solution, as it changes the environment of the local process, and those changes will be inherited by any process started with subprocess.run.

You can also use the env argument to run:

subprocess.run(["cmdname", "arg1", "arg number 2"], env=dict(FOO='BAR', **os.environ))

This runs the command in a modified environment that includes FOO=BAR without modifying the current environment.

Sign up to request clarification or add additional context in comments.

4 Comments

Ahhh. So is my only option to use os.environ, or is there something else I can do?
I'm not sure why you are objecting to using os.environ so much. That is the Python equivalent of using the shell's builtin export command in a shell script.
Like I said, I expect to be stringing multiple commands together; I believe it would be easier to add export to a list of commands I will need to execute, rather than do so in a separate python function. That's fine though, I can figure something out. Thanks for your answer, it explained why it wasn't working as I expected :)
you could use dict(os.environ, FOO='BAR') instead of dict(FOO='BAR', **os.environ)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.