我正在为生物信息学工具开发一个自动化框架。由于我的程序将使用的大多数软件都是为 Linux 编写的,而不是用 python 编写的,所以我使用 subprocess 来调用这些进程。我遇到的问题是管道中的许多步骤需要很长时间,我想查看实时输出,所以我知道它仍在工作并且没有挂起或其他东西。但我还需要在该过程完成后捕获输出以记录任何意外错误。
我发现 subprocces.Popen() 是我解决这个问题所需要的。
这是我使用的代码(在这里找到:https ://fabianlee.org/2019/09/15/python-getting-live-output-from-subprocess-using-poll/ ):
# invoke process
process = subprocess.Popen("./test.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# print stdout while process is still working
while True:
output = process.stdout.readline()
if process.poll() is not None:
break
if output:
print("out:", output.strip())
rc = process.poll()
if rc == 0:
print("Process ended with rc:", rc, "output:", output)
else:
print("Process ended with rc:", rc, "error:", process.stderr.readline())
当我使用这个简单的 bash 脚本作为参数时,它就像一个魅力:
#!/bin/bash
for i in $(seq 1 5); do
echo "iteration" $i
sleep 1
done
这给出了输出:
out: iteration 1
out: iteration 2
out: iteration 3
out: iteration 4
out: iteration 5
Process ended with rc: 0 output:
或者如果我故意在脚本中插入错误,例如:
Process ended with rc: 2 error: ./test.sh: line 7: syntax error: unexpected end of file
但是,当我使用(在这种情况下为 picard ValidateSamFile)尝试它时,无论我尝试了什么,它都不会给我任何 livefeed:
# invoke process
process = subprocess.Popen("picard ValidateSamFile -I dna_seq/aligned/2064-01/AHWM2NCCXY.RJ-1967-2064-01.6.bam", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# print stdout while process is still working
while True:
output = process.stdout.readline()
if process.poll() is not None:
break
if output:
print("out:", output.strip())
rc = process.poll()
if rc == 0:
print("Process ended with rc:", rc, "output:", output)
else:
print("Process ended with rc:", rc, "error:", process.stderr.readline())
该过程完成后我得到这个:
out: No errors found
Process ended with rc: 0 output:
有任何想法吗?