我已经在 SO 和其他网站上阅读了一堆不同的主题,但无法得到我的问题/问题的直接答案。目前,我有一个运行完全正常的 python 脚本,除了没有调用运行 Fortran 程序时可以正常工作。我尝试过使用 subprocess 命令、os.system 命令、打开通过 python 打开的 bash 脚本文件,但没有成功。以下是我遇到的一些示例和错误。
一次尝试:
subprocess.Popen(["sh", "{0}{1}".format(SCRIPTS,"qlmtconvertf.sh"), "qlmt"], shell=False, stdout=subprocess.PIPE)
这会给出一个错误,表明程序无法正确读取文件。
forrtl: severe (24): end-of-file during read, unit 1, file /home/akoufos/lapw/Ar/lda/bcc55_mt1.5_lo_e8_o4/DOS/lat70/qlmt
另一次尝试:
subprocess.Popen(["./{0}{1}".format(SOURCE,"qlmtconvertf"), "qlmt"], shell=False, stdout=subprocess.PIPE)
这会导致找不到文件的错误。
File "/home/akoufos/lapw/Scripts_Plots/LAPWanalysis.py", line 59, in DOS
subprocess.Popen(["./{0}{1}".format(SOURCE,"qlmtconvertf"), "qlmt"], shell=False, stdout=subprocess.PIPE)
File "/usr/lib64/python2.7/subprocess.py", line 672, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1202, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
又一次尝试:
os.system("{0}{1}".format(SOURCE,"qlmtconvertf qlmt"))
这给出了与第一个示例等效的错误。在所有示例中,SOURCE =“/home/myusername/lapw/Source/”,其中fortran源文件为SCRIPTS =“/home/myusername/lapw/Scripts_Plots/”,其中我有其他文件和python脚本,qlmtconvertf是编译后的 fortran 程序,qlmt 是 qlmtconvertf 读取的文件。如果我在 shell 中调用此源代码,它可以完全正常工作,就像我已经做过无数次一样,但我正在尝试自动调用这些代码。我也写了一个 bash 脚本,它可以满足我的需要,但我试图通过 python 来完成所有事情。对于我做错的事情和正在发生的事情的任何想法、建议或答案将不胜感激。提前谢谢大家。
编辑:我按照弗朗西斯下面给出的建议工作了。我必须保留完整路径(即/home/username/etc)和 os.path.join 才能正确调用程序。
import os.path
LAPW = "/home/myusername/lapw/"
SOURCE = os.path.join(LAPW,'Source')
SCRIPTS = os.path.join(LAPW,'Scripts_Plots')
QLMTCONVERT = os.path.join(SOURCE,'qlmtconvertf')
qargs = [QLMTCONVERT,'qlmt']
#CALLING PROGRAM
subprocess.Popen(qargs, stdout=subprocess.PIPE).communicate(input=None)
为了让它正常工作,我还必须关闭在 python 脚本期间创建的“qlmt”文件。我还在包含“qlmt”文件的目录中工作。
(编辑还在子流程的末尾添加了.communicate(input=None)
。这对于此流程调用来说是不必要的,但对于后者很重要我在脚本中制作了一个尝试使用进程正在创建的文件的脚本。根据我的理解,.communicate
与进程对话,基本上等待它完成,然后再执行下一个 python 行。类似到 .wait()
,但更高级。如果更了解这一点的人想要详细说明,请随意。编辑)
我不太确定为什么这个方法有效,但是使用字符串作为子进程的输入会产生错误。如果有人对此有任何见解,如果您能传授您的知识,我将非常感激。谢谢大家的帮助。
最佳答案
我认为您忘记了文件名中的斜杠:
"{0}{1}".format(SOURCE,"qlmtconvertf qlmt") == '/home/myusername/lapw/Sourceqlmtconvertf qlmt'
我想你的意思是这个?
"{0}/{1}".format(SOURCE,"qlmtconvertf qlmt") == '/home/myusername/lapw/Source/qlmtconvertf qlmt'
我建议使用os.path.join
而不是直接构造字符串来创建路径名:
import os.path
executable = os.path.join(SOURCE, 'qlmtconvertf')
args = ['qlmt']
subprocess.Popen(executable+args, stdout=subprocess.PIPE)
关于python - 似乎无法让 fortran 可执行文件通过 python 正确运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10656863/