在cmd中通过Python运行工具时不等待

2 投票
2 回答
506 浏览
提问于 2025-04-18 09:24

我在命令行(cmd)里用 Python 运行一个工具。我想让这个工具对指定文件夹里的每个样本都做一些事情。但是,当我在循环里用 process = subprocess.Popen(command) 时,命令没有等到完成就继续执行,结果是一次性出现了10个提示符。而当我使用 subprocess.Popen(command, stdout=subprocess.PIPE) 时,命令窗口是黑的,我看不到进度,虽然它确实会等到命令完成。

有没有人知道怎么通过 Pythoncmd 里调用一个外部工具,让它等到命令完成后再继续,并且能够在 cmd 中显示工具的进度?

#main.py
        for sample in os.listdir(os.getcwd()):
            if ".fastq" in sample and '_R1_' in sample and "Temp" not in sample:
                print time.strftime("%H:%M:%S")
                DNA_Bowtie2.DNA_Bowtie2(os.getcwd()+'\\'+sample+'\\'+sample)

#DNA_Bowtie2.py
            # Run Bowtie2 command and wait for process to be finished.
            process = subprocess.Popen(command, stdout=subprocess.PIPE)
            process.wait()
            process.stdout.read()

补充说明:command 是一个 perl 或 java 的命令。用上面的方式我看不到工具的输出,因为提示符(perl 窗口或 java 窗口)是黑的。

2 个回答

0

这里的顺序很重要:先读取输出,然后再等待。

如果你这样做:

process.wait()
process.stdout.read()

你可能会遇到死锁的情况,如果管道的缓冲区完全满了:子进程在等待标准输出(stdout),而永远无法结束,你的程序在 wait() 上也会被卡住,永远无法执行 read()

应该这样做:

process.stdout.read()
process.wait()

这样可以一直读取,直到到达文件结束符(EOF)。

这适用于你想要获取进程的标准输出的情况。

如果你不需要这些输出,就可以省略 stdout=PIPE 的部分。这样输出就会直接显示在那个提示窗口里。然后你也可以省略 process.stdout.read()

通常情况下,process.wait() 应该能防止同时运行10个实例。如果这不奏效,我也不知道为什么……

1

看起来你的子进程是分叉的,否则在进程完成之前,wait() 是不可能返回的。

撰写回答