How to control a process environment variable in Python?

I am trying to change the environment of my Python runtime. It seems that the right way to do this should be to interact with os.environ. However, I do not fulfill the following statement:

import os, subprocess os.environ['ATESTVARIABLE'] = 'value' value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True) assert 'value' in value 

Is there anything else I have to do to change the current environment? What flaw in my understanding of Python is revealed by the code above :)?

(Note that in the current Python interpreter, os.environ['ATESTVARIABLE'] contains the expected value. I configure the execution of some code that requires a specific environment variable and that can run external processes. Obviously, if I wanted to control the environment of a particular subprocess I would use the env keyword.)

+4
source share
2 answers

Looking through the source code of the subprocess module, because using a list of arguments with shell=True will do the equivalent ...

 /bin/sh -c 'echo' '$ATESTVARIABLE' 

... when do you want...

 /bin/sh -c 'echo $ATESTVARIABLE' 

The following works for me ...

 import os, subprocess os.environ['ATESTVARIABLE'] = 'value' value = subprocess.check_output('echo $ATESTVARIABLE', shell=True) assert 'value' in value 

Update

FWIW, the difference between the two is that the first form ...

 /bin/sh -c 'echo' '$ATESTVARIABLE' 

... will just call the shell of the built-in echo with no parameters and set $0 to the literal string '$ATESTVARIABLE' , for example ...

 $ /bin/sh -c 'echo $0' /bin/sh $ /bin/sh -c 'echo $0' '$ATESTVARIABLE' $ATESTVARIABLE 

... whereas the second form ...

 /bin/sh -c 'echo $ATESTVARIABLE' 

... will invoke the built-in echo shell with a single parameter equal to the value of the ATESTVARIABLE environment ATESTVARIABLE .

+3
source

Actually, what is wrong in the following code:

 import os, subprocess os.environ['ATESTVARIABLE'] = 'value' value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True) assert 'value' in value 

is that you did not fully read the subprocess 's help page:

On Unix with shell = True, the shell defaults to / bin / sh. If args is a string, the string indicates the command to execute through the shell. This means that the string must be formatted exactly the same as when typing on the command line. This includes, for example, quoting or backslashes with escaping file names with spaces in them. If args is a sequence, the first element indicates the command line, and any additional elements will be considered as additional arguments to the shell itself . That is, Popen makes the equivalent:

 Popen(['/bin/sh', '-c', args[0], args[1], ...]) 

This means that if you call subprocess.check_out() with an array as the first parameter, you will not get the expected result. Try again with the following code:

 import os, subprocess os.environ['ATESTVARIABLE'] = 'value' value = subprocess.check_output('echo $ATESTVARIABLE', shell=True) assert 'value' in value 

and it should work as you expect!

Otherwise, your understanding of environment variables will be correct. When you change the environment, this environment is provided to each bifurcated child of your current process.

+3
source

Source: https://habr.com/ru/post/1488164/


All Articles