启动子流程,等待它完成,然后在Python

时间:2016-06-19 23:26:27

标签: python linux subprocess

我很难获得一些python脚本来启动子进程,等到它完成然后检索所需的数据。我对Python很陌生。

我希望作为子进程运行的命令是

    ./bin.testing/Eva -t --suite="temp0"

在Linux终端中手动运行该命令会产生:

    in terminal mode
    Evaluation error = 16.7934

我想将命令作为python子进程运行,并接收输出。但是,我尝试的所有内容似乎都跳过第二行(最终,它是我想要的第二行。)目前,我有这个:

    def job(self,fen_file):
        from subprocess import Popen, PIPE
        from sys import exit

        try:
            eva=Popen('{0}/Eva -t --suite"{0}"'.format(self.exedir,fen_file),shell=True,stdout=PIPE,stderr=PIPE)            
            stdout,stderr=eva.communicate()
        except:
            print ('Error running test suite '+fen_file)
            exit("Stopping")

        print(stdout) 
        .
        .
        .
        return 0

所有这些似乎产生了

    in terminal mode

    0

缺少重要的一行。 print语句就是这样,我可以看到我从子进程中得到什么 - 意图是它将被替换为处理第二行中的数字并返回输出的代码(这里我只是返回0只是因为我可以让这个特定的位首先工作。这个函数的调用者打印结果,这就是为什么在输出的末尾有一个零。)exedir只是子进程的可执行文件的目录和fen-file只是子进程所需的ascii文件。我已经尝试从子进程的源代码中删除'in terminal mode'并重新编译它,但这不起作用 - 它仍然没有返回重要的第二行。

提前致谢;我希望我做错的事情非常简单。

编辑:我应该补充说,子流程Eva可能需要一两秒才能完成。

2 个答案:

答案 0 :(得分:2)

由于第二行是错误消息,它可能存储在您的stderr变量中!

要确定您可以在代码中打印stderr,或者可以在命令行上运行该程序,看看输出是否分为stdoutstderr。一种简单的方法是./bin.testing/Eva -t --suite="temp0" > /dev/null。您收到的所有邮件都是stderr,因为stdout被重定向到/dev/null

此外,通常使用Popen,除非确实需要,否则不建议使用shell=True选项。而是传递一个列表:

[os.path.join(self.exedir, 'Eva'), '-t', '--suite=' + fen_file], shell=False, ...

如果你的一个参数通常由shell解释,这可以避免问题。 (注意,我删除了"",因为shell通常会为你吃掉那些!)

答案 1 :(得分:0)

尝试使用子进程check_output。

output_lines = subprocess.check_output(['./bin.testing/Eva', '-t', '--suite="temp0"'])
for line in output_lines.splitlines():
    print(line)