Python - 使用os.popen()解析Unix的“ls” - 终止子进程的问题

0 投票
2 回答
1743 浏览
提问于 2025-04-16 01:51

根据我的理解,os.popen() 是在 Python 中打开一个管道,并启动一个新的子进程。当我在使用 os.popen() 的时候,运行一个 for 循环时遇到了问题。我发现我无法通过 CTRL+C 退出这个循环。以下是我的代码:

for FILE in os.popen("ls $MY_DIR/"):
    os.system("./processFile " + FILE)

每当我尝试按 CTRL+C 时,Python 会停止 ./processFile 这个程序,但不会停止 Python 本身的程序!

我在网上搜索过,但似乎找不到正确的答案。有些人建议使用信号(我试过了……没用)。还有人尝试使用进程 ID(PID)来杀掉子进程的 PID,但我也搞不定。

有没有人能给我一个更好的例子,让我可以在按 CTRL+C(SIGINT)时停止程序?

2 个回答

2

这个行为是正常的。按下 Ctrl+C 会停止当前正在运行的程序,而不是它的父程序。在这里调用命令行并使用 ls 并不合适,你的代码应该更好地写成下面这样(未经测试):

import os
import subprocess
for fname in os.listdir(directory):
    path = os.path.join(directory, fname)
    subprocess.check_call(["./processFile", path])
3

我看到有些回答正确地推荐了 subprocess.check_call,而提问者在评论中提到:

我遇到了这个错误: AttributeError: 'module' object has no attribute 'check_call'

根据我刚刚提到的文档,check_call 被标记为:

在2.5版本中新增。

所以看起来提问者使用的是一个很老的Python版本——2.4或更早的版本——而没有提到这一点(现在的稳定版本是2.7,而2.4已经很多年没更新了)。

因此,最好的建议就是升级!如果你觉得2.7“太新”了(在一些保守的环境中可能会这样认为),那么2.6的最新小版本应该也没问题——它不仅会给你带来subprocess.check_call,还会有很多额外的功能、修复的bug和优化!-)

撰写回答