Python子进程没有正确执行程序

时间:2013-03-28 20:43:25

标签: python subprocess

我正在尝试从Python中执行shell中的Fortran程序。 我正在使用subprocess来调用Fortran程序并传递参数(需要两个输入文件)。我就是这样做的:

COMMAND = '/path/to/FORTRAN/program << !\n' + INPUT_FILE1 + '\n' + INPUT_FILE2 +'\n!'
return = subprocess.call(COMMAND, shell=True)

不幸的是,Fortran程序以:

退出
? FORTRAN Runtime Error:
? Attempt to read past end of file
? READ(UNIT=22,...

这是输入文件或Fortran程序的问题。当我在我的shell中执行它时:

$>/path/to/FORTRAN/program << !
>INPUT_FILE1
>INPUT_FILE2
>!

一切都按预期工作(没有Attempt to read past end of file)。

我无法访问Fortran源代码,因此我无法检查其中发生了什么。我认为这与我通过subprocess调用程序的方式有关 - 我无法弄清楚是什么。

我正在使用Python 2.6.6。

快速解释:Fortran程序将提示输入两个文件,但它不会将它们识别为命令行选项(它们无法通过调用程序提供)。如果你想运行它 - 比如一个shell脚本(批处理模式) - 你需要捕获return命令来执行命令,还要提供这两个文件。由于缺少更好的术语,<< !会打开“列表”。以下命令将传递给程序,该程序将执行,直到键入!为止。

我已成功多次使用此方法(不同的Fortran代码),并使用此C shell脚本(不是Python)。

3 个答案:

答案 0 :(得分:1)

可能是由shell=True调用的shell引起的,如果它没有在您的系统上调用bash。您可以避免依赖于扩展shell语法<<,而是自己构建整个调用,如:

popen = subprocess.Popen(["/path/to/FORTRAN/program"], stdin=subprocess.PIPE)
popen.stdin.write('123\n')
time.sleep(0.1)    # hack, following LAK's suggestion
popen.stdin.write('456\n')
popen.stdin.close()
result = popen.wait()

答案 1 :(得分:1)

我曾经有过类似的问题,而且解决方案原来是添加一个小暂停。看看this,看看这种技术是否有帮助。

答案 2 :(得分:1)

您可以尝试"\r\n"(tty换行符):

from subprocess import Popen, PIPE

p = Popen(["/path/to/FORTRAN/program"], stdin=PIPE,
          bufsize=1, close_fds=True)
p.communicate("INPUT_FILE1\r\nINPUT_FILE2")
rc = p.returncode

最后有/ "\r\n"