export – set environment variable in python script
export – set environment variable in python script
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))
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)
export – set environment variable in python script
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 cant avoid it at least use python3s 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 processs 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 wont affect pythons 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]