如何在Python中的另一个命令之后调用子进程?

时间:2017-03-30 11:38:53

标签: python subprocess

我想编写Python脚本。我是新来的。在那个脚本中,我想运行另一个C程序,它在输出中提供了许多数字。 Smth喜欢:

1   1   0.000000    0.000172    0.075010    0.937330    33.743876

我希望使用其他参数多次运行此程序,并在一个文件中收集所有输出。之后,我计划使用pandas对数据进行排序并制作一些图表,但现在并不重要。我写了以下代码:

import subprocess

f = open("ax-rrff.dat", "w")
f.write("seed\tN\tT\tDRA\tD\tActive\tAvF\n")

p = subprocess.call(['gcc', 'ax-rrff.c', '-lm','-lgsl','-lgslcblas'])

for seed in range(1,2+1):
    for N in range(1,2+1):
        p = subprocess.call(['a.exe',str(seed),'1',str(N),'1000','0','0'], stdout=f)

f.close()

(小数字只是为了告诉你)。我希望我的ax-rrff.dat

seed    N   T   DRA D   Active  AvF
1   1   0.000000    0.000172    0.075010    0.937330    33.743876
1   2   0.000000    0.003598    0.021690    1.564677    14.032332
2   1   0.000000    0.000172    0.062262    0.925817    33.329404
2   2   0.000000    0.002790    0.014749    1.423670    16.689964

然而,编译器的调度程序认为以这种方式输出会很酷:

1   1   0.000000    0.000172    0.075010    0.937330    33.743876
1   2   0.000000    0.003598    0.021690    1.564677    14.032332
2   1   0.000000    0.000172    0.062262    0.925817    33.329404
2   2   0.000000    0.002790    0.014749    1.423670    16.689964
seed    N   T   DRA D   Active  AvF

问题。如何强制子流程在f.write("seed\tN\tT\tDRA\tD\tActive\tAvF\n")之后运行?

2 个答案:

答案 0 :(得分:1)

好的,我是电话,所以无法测试我的答案,但我猜你的预期输出可以这样实现:

import subprocess 
f = open("ax-rrff.dat", "a")
f.write("seed\tN\tT\tDRA\tD\tActive\tAvF\n")

p = subprocess.call(['gcc', 'ax-rrff.c', '-lm','-lgsl','-lgslcblas']) 

for seed in range(1,2+1): 
    for N in range(1,2+1): 
        newcall = subprocess.Popen(['a.exe',str(seed),'1',str(N),'1000','0','0'], stdout=subprocess.PIPE) 
        newcall.wait()
        output, errors = newcall.communicate()
        f.write(output.decode())

f.close()

这会让一件事情不清楚..因为你在for循环之外声明p然后再在其中声明一次..这使我相信你愿意使用第一个声明作为输入第二个..然而,你正在做的只是做一个新的声明,从而覆盖第一个。所以你正在改变p,而不是以任何方式使用/执行它。

进一步解释:

我将open(file, 'w')更改为open(file, 'a'),这意味着该文件将是append模式,而不是write模式。这允许您按照自己喜欢的方式编写,并且它将按照从python脚本中的文件写入文件的顺序添加每一行。

如果您仍然希望使用p的第一个声明作为第二个声明的输入,请查看是否可以通过扩展命令行命令来插入for循环中的子进程。< / p>

答案 1 :(得分:1)

问题是write()将输出放在缓冲区中,并且只定期将缓冲区刷新到磁盘。由于您有多个进程写入文件,因此他们可能会在父进程执行之前刷新自己的缓冲区。要强制输出,只需在开始任何子进程之前调用f.flsuh()