摘要
我正在尝试通过子过程调用命令来调用外部程序。 直接从终端调用时,我的程序运行良好。但是,通过子流程调用时,程序将引发错误。
详细信息
我正在尝试用Python调用程序Zimpl。 Zimpl是一个程序,可以读取模型文件以及两个输入文件并生成一个输出文件。
当我通过命令行调用Zimpl时,输出如下:
****************************************************
* Zuse Institute Mathematical Programming Language *
* Release 3.3.2 Copyright (C)2012 by Thorsten Koch *
****************************************************
* This is free software and you are welcome to *
* redistribute it under certain conditions *
* ZIMPL comes with ABSOLUTELY NO WARRANTY *
****************************************************
Reading model.zpl
Reading parfile.par
Reading values.txt
Instructions evaluated: 103351
Name: model.zpl Variables: 156 Constraints: 546 Non Zeros: 2280
Writing [model.lp]
Writing [model.tbl]
当我使用以下命令通过子流程库调用时:
s = subprocess.check_call(['zimpl', 'model.zpl'])
print(s)
这是我得到的:
****************************************************
* Zuse Institute Mathematical Programming Language *
* Release 3.3.2 Copyright (C)2012 by Thorsten Koch *
****************************************************
* This is free software and you are welcome to *
* redistribute it under certain conditions *
* ZIMPL comes with ABSOLUTELY NO WARRANTY *
****************************************************
Reading model.zpl
Reading parfile.par
Reading values.txt
*** Error 800: File model.zpl Line 24 : Symbol "VALUE" not initialised
*** ximize obj : sum <i,j> in Particles : (x[i,j] * VALUE[i,j]);
*** ^^^
Traceback (most recent call last):
File "./runscript.py", line 153, in <module>
evaluateLevel(0, sublevels[0], values)
File "./runscript.py", line 111, in evaluateLevel
s = subprocess.check_call(['zimpl', 'model.zpl'])
File "/Users/macbook/anaconda2/lib/python2.7/subprocess.py", line 541, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['zimpl', 'model.zpl']' returned non-zero exit status 1
在Zimpl模型文件中,启动VALUE的行是这样的:
param VALUE[Particles] := read "values.txt" as "<1n,2n> 3n";
换句话说,从文件中读取了VALUE。我什至去了Zimpl的源代码,看看何时出现错误“ Symbol .. not initialized”。这是我发现的:
case SYM_ERR : /* should not happen */
sprintf(errmsg, "Symbol \"%s\" not initialised\n", yytext);
yyerror(errmsg);
我不知道为什么会这样。我的猜测是,它可能与缓冲区有关,或者执行程序太快而导致Zimpl没有时间读取data.txt文件。
它变得更加有趣。如果我调用Popen命令并打印输出,则该程序仅部分运行。
proc = subprocess.Popen(["zimpl",
"model.zpl"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
bufsize=0)
proc.wait() # I tried with and without this line, same output
for line in proc.stdout:
print(line),
****************************************************
* Zuse Institute Mathematical Programming Language *
* Release 3.3.2 Copyright (C)2012 by Thorsten Koch *
****************************************************
* This is free software and you are welcome to *
* redistribute it under certain conditions *
* ZIMPL comes with ABSOLUTELY NO WARRANTY *
****************************************************
Reading model.zpl
Reading parfile.par
Reading values.txt
尽管现在它不会引发错误,但不会生成应有的文件。现在..如果我不尝试通过删除以下行来打印标准输出:
for line in proc.stdout:
print(line),
Voila !!尽管我看不到程序的输出,但文件已生成。为什么会这样呢?我没有提到我尝试过的所有事情,例如使用参数,尝试不同的buffsize,使用子进程库中的其他命令等。而且,如果我想查看程序的输出,则不会。
最后,如果我运行命令:
proc = subprocess.Popen(["zimpl",
"model.zpl"],
stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
bufsize=0)
这将正确生成输出和文件,但是程序挂起并等待输入:
****************************************************
* Zuse Institute Mathematical Programming Language *
* Release 3.3.2 Copyright (C)2012 by Thorsten Koch *
****************************************************
* This is free software and you are welcome to *
* redistribute it under certain conditions *
* ZIMPL comes with ABSOLUTELY NO WARRANTY *
****************************************************
Reading model.zpl
Reading parfile.par
Reading values.txt
MacBook-Pro:model macbookpro$ Instructions evaluated: 103351
Name: model.zpl Variables: 156 Constraints: 546 Non Zeros: 2280
Writing [model.lp]
Writing [model.tbl]
如果有人能解释发生了什么并提出一种产生输出和文件,程序正常终止而无需等待输入的方式,我将不胜感激。