Python子过程 /环境变量脚本
我有一个编译的fortran程序(在〜/codedir
中)链接到Intel MKL,我想在某个目录中使用Python脚本运行(假设calculationDir
> )。 我可以导航到calculationDir
并执行〜/codedir/code
,其中代码是可执行文件的名称。一切都起作用。但是,如果我尝试从下面的Python脚本启动代码:
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()
我会收到以下错误:
/home/codedir/code: error while loading shared libraries: libmkl_intel_lp64.so.1: cannot open shared object file: No such file or directory
我怀疑这可能与环境变量有关。我配置了我的外壳,每次启动shell时,都执行了一个Intel One API的脚本setVars.shsevars.sh
,该API设置了很多东西。如果我使用Python的子过程,这些变量是否可以设置?我是否必须以某种方式告诉子过程才能执行setVars-script
?
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
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您似乎正在寻找
There is no need to specify
shell=True
,事实上,当您自己拆分命令时,在类 Unix 平台上这样做是错误的。 (Windows 上的语义略有不同,因此虽然它仍然是一个错误,但症状可以忽略不计。)另请参阅subprocess
中shell=True
的实际含义split
是错误的,因为它不知道如何实现应付反斜杠转义和引用;如果您的命令当前不包含这些构造中的任何一个,您可以使用基本字符串split
;但标准库提供了一个无论如何都能正常工作的函数,我认为没有理由不在这里使用shlex.split
。正如文档所解释的,如果可以的话,您应该更喜欢
subprocess.run
而不是普通的Popen
,因为后者需要您复制/粘贴几行样板代码,即使这样除非您确切地知道自己在做什么,否则不太健壮,可能会以添加更多用于错误处理等的样板代码为代价。最后,真正的牛肉:关键字参数
cwd
允许您设置工作子进程的目录。You seem to be looking for
There is no need to specify
shell=True
and 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=True
insubprocess
Plain
split
is 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.split
here.As the documentation explains, you should prefer
subprocess.run
over plainPopen
when 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
cwd
allows you to set the working directory of the subprocess.