I have a compiled Fortran program (lets say in ~/codedir) linked against Intel MKL, which I want to run with a Python script in a certain directory (lets say calculationdir).
I can navigate to calculationdir and execute ~/codedir/code, where code is the name of the executable. Everything works. But if I try to start the code from the below Python script:
import subprocess
command = '~/codedir/code'
with open('job.out', 'a') as f:
process = subprocess.Popen(command.split(), stdout=f, shell=True)
output, error = process.communicate()
I get the following error:
/home/codedir/code: error while loading shared libraries: libmkl_intel_lp64.so.1: cannot open shared object file: No such file or directory
I suspect that this might have something to do with the environment variables. I configured my shell that every time I start a shell, the script setvars.sh of Intel One API is executed which sets a lot of things. Could it be case that these variable are not set if I use python's subprocess? Do I have to tell subprocess in some way to execute also the setvars-script?
You seem to be looking for
There is no need to specify
shell=Trueand in fact, when you split the command yourself, it's an error to do so on Unix-like platforms. (The semantics are slightly different on Windows, so while it's still an error, the symptoms are negligible.) See also Actual meaning ofshell=TrueinsubprocessPlain
splitis wrong because it doesn't know how to cope with backslash escapes and quoting; if your command doesn't currently contain either of those constructs, you can get away with a basic stringsplit; but the standard library supplies a function which works correctly regardless, and I see no reason not to useshlex.splithere.As the documentation explains, you should prefer
subprocess.runover plainPopenwhen you can, as the latter requires you to copy/paste several lines of boilerplate code, and even then is less robust unless you know exactly what you are doing, probably at the expense of adding even more boilerplate code for error handling etc.Finally, the actual beef: the keyword argument
cwdallows you to set the working directory of the subprocess.