Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set environment variable in python script

Tags:

python

export

I have a bash script that sets an environment variable an runs a command

LD_LIBRARY_PATH=my_path
sqsub -np $1 /homedir/anotherdir/executable

Now I want to use python instead of bash, because I want to compute some of the arguments that I am passing to the command.

I have tried

putenv("LD_LIBRARY_PATH", "my_path")

and

call("export LD_LIBRARY_PATH=my_path")

followed by

call("sqsub -np " + var1 + "/homedir/anotherdir/executable")

but always the program gives up because LD_LIBRARY_PATH is not set.

How can I fix this?

Thanks for help!

(if I export LD_LIBRARY_PATH before calling the python script everything works, but I would like python to determine the path and set the environment variable to the correct value)

like image 447
Matthias 009 Avatar asked Dec 03 '11 03:12

Matthias 009


People also ask

How do you set environment variables in Python?

With the environ dictionary variable value of the environment variable can be set by passing the key in the dictionary and assigning the value to it. With setdefault a default value can be assigned to the environment variable. Bypassing the key and the default value in the setdefault method.

How do I set an environment variable in Python terminal?

To set and get environment variables in Python you can just use the os module: import os # Set environment variables os. environ['API_USER'] = 'username' os. environ['API_PASSWORD'] = 'secret' # Get environment variables USER = os.

How do I set environment variables?

On the Windows taskbar, right-click the Windows icon and select System. In the Settings window, under Related Settings, click Advanced system settings. On the Advanced tab, click Environment Variables. Click New to create a new environment variable.


3 Answers

bash:

LD_LIBRARY_PATH=my_path
sqsub -np $1 /path/to/executable

Similar, in Python:

import os
import subprocess
import sys

os.environ['LD_LIBRARY_PATH'] = "my_path" # visible in this process + all children
subprocess.check_call(['sqsub', '-np', sys.argv[1], '/path/to/executable'],
                      env=dict(os.environ, SQSUB_VAR="visible in this subprocess"))
like image 87
jfs Avatar answered Oct 28 '22 23:10

jfs


You can add elements to your environment by using

os.environ['LD_LIBRARY_PATH'] = 'my_path'

and run subprocesses in a shell (that uses your os.environ) by using

subprocess.call('sqsub -np ' + var1 + '/homedir/anotherdir/executable', shell=True)
like image 24
Manbeardo Avatar answered Oct 28 '22 22:10

Manbeardo


There are many good answers here but you should avoid at all cost to pass untrusted variables to subprocess using shell=True as this is a security risk. The variables can escape to the shell and run arbitrary commands! If you just can't avoid it at least use python3's shlex.quote() to escape the string (if you have multiple space-separated arguments, quote each split instead of the full string).

shell=False is always the default where you pass an argument array.

Now the safe solutions...

Method #1

Change your own process's environment - the new environment will apply to python itself and all subprocesses.

os.environ['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)

Method #2

Make a copy of the environment and pass is to the childen. You have total control over the children environment and won't affect python's own environment.

myenv = os.environ.copy()
myenv['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command, env=myenv)

Method #3

Unix only: Execute env to set the environment variable. More cumbersome if you have many variables to modify and not portabe, but like #2 you retain full control over python and children environments.

command = ['env', 'LD_LIBRARY_PATH=my_path', 'sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)

Of course if var1 contain multiple space-separated argument they will now be passed as a single argument with spaces. To retain original behavior with shell=True you must compose a command array that contain the splitted string:

command = ['sqsub', '-np'] + var1.split() + ['/homedir/anotherdir/executable']
like image 19
Thomas Guyot-Sionnest Avatar answered Oct 28 '22 22:10

Thomas Guyot-Sionnest