【发布时间】:2012-05-26 06:40:09
【问题描述】:
我在 SO 和其他网站上阅读了许多不同的主题,但无法直接回答我的问题。目前我有这个运行完全正常的python脚本,除了没有调用运行fortran程序正常工作。我尝试过使用子进程命令、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”文件的目录中工作。
(edit 还在子进程的末尾添加了.communicate(input=None)。这对于此进程调用来说是不必要的,但对于我在脚本中尝试使用进程正在创建的文件。据我了解,.communicate 与进程对话,基本上在执行下一条 python 行之前等待它完成。类似于.wait(),但更高级。如果更了解这一点的人想要详细说明,请随意。编辑)
我不确定为什么这种方法有效,但是使用字符串作为子进程的输入会产生错误。如果有人对此有任何见解,如果您能传授您的知识,我将不胜感激。谢谢大家的帮助。
【问题讨论】:
-
你试过
shell=True吗?我通常在调用外部程序时发现这是必要的。 -
你写这些帖子的方式很有趣,看了 20 遍,仍然忘记提及。我在第二个例子中尝试了
shell=True,有和没有./。两者似乎都不起作用。我也尝试使用~/lapw作为文件夹名称而不是完整路径。同样,这两种方法都不会给出更多有用的错误。在第一个示例中尝试它会打开 shell 提示符,但似乎也不起作用,但不会运行程序。我将对此进行更多研究,因为似乎没有调用 qlmtconvert。感谢您的建议。 -
在尝试运行可执行文件之前,您是否尝试将当前工作目录更改为可执行文件所在的目录?我使用了几个希望从它们的目录运行的 fortran 程序。
-
@arifwn:不,我没有,但这应该不是问题,正如我在上面建议的那样,如果我单独在 shell 中调用它,程序运行良好。即我在包含“qlmt”的目录中工作时从 shell 调用
/home/myusername/lapw/Source/qlmtconvertf qlmt。感谢您的建议。 -
@falconskull:是的,有时要记住的东西太多了。很高兴您似乎找到了解决方案。 FWIW,我尝试使用
subprocess调用(.call()和.Popen())从 Python 程序运行一个非常简单的 FORTRAN 程序,发现我需要shell=True才能使其工作。但是,您似乎在 Windows 上(我现在无法访问)而我在 Linux 上,所以 YMMV。
标签: python fortran subprocess os.system