使用子流程关闭图像

时间:2016-12-17 05:25:27

标签: python python-3.x subprocess kill terminate

我正在尝试使用子进程打开图像,以便用户可以看到它,然后关闭图像以使其消失。

之前已经问过这个问题,但我找到的答案对我没用。这是我检查的内容:

Killing a process created with Python's subprocess.Popen()

How to terminate a python subprocess launched with shell=True

How can I close an image shown to the user with the Python Imaging Library?

我需要代码来打开图像(使用预览(可选),默认在我的Mac上),等待一秒钟,然后关闭图像。

openimg = subprocess.Popen(["open", mypath])
time.sleep(1)
openimg.terminate()
openimg.kill()

一切都告诉我终止()和杀死(),但仍然没有关闭图像。

这不是必须使用预览,我也愿意听其他选项。

编辑:我已经尝试了下面的代码,仍然没有成功

print('openimg\'s pid = ',openimg.pid)
os.kill(openimg.pid, signal.SIGKILL)

2 个答案:

答案 0 :(得分:1)

OS X的open命令是异步的 - 它会产生预览过程(或它启动的任何应用程序)并立即退出。因此,当您的Python代码调用terminate()kill()时,open进程就完成了。它已不存在。

您可以通过传递open选项

来强制执行同步行为,即让-W保持运行直到预览退出之后
subprocess.Popen(["open", "-W", mypath])

这样,当您的代码开始运行openterminate时,kill仍将继续运行。 (我建议也传递-n选项,以确保预览启动一个新实例,以防你之前有另一个预览实例。)当open进程结束时,希望它会也结束了底层的预览过程。您可以使用pspgrep等进程查看器检查是否确实发生了这种情况。

如果终止或终止open没有杀死预览,则您需要更改配置,以便在您致电open时将信号传递到terminate()的所有子流程或kill()this questionthis one 可能有用,或者您必须找到一种方法来获取预览的进程ID并将信号发送到直接,这将要求你超越Popen。我不确定这样做的最佳方式,但也许其他人可以提供一个能够告诉你如何做出的答案。

答案 1 :(得分:1)

我确信这是最常用的方法,但是,它很有效。如果有人偶然发现并知道更好的方法,请告诉我。

问题 正如David Z所述,我没有针对正确的流程。所以我必须弄清楚正确的进程ID是什么才能正确关闭它。

我开始打开终端并输入命令ps -A。这将显示所有当前打开的进程及其ID。然后我搜索Preview并找到两个打开的进程。

之前,我正在关闭列表中的第一个预览pid,我们称之为11329,但列表中的第二个仍处于打开状态。第二个预览流程11330始终比第一个流程高1位数。第二个是我需要定位以关闭预览的pid。

答案

openimg = subprocess.Popen(["open", mypath]) ##Opens the image to view
newpid = openimg.pid + 1 ##Gets the pid 1 digit higher than the openimg pid. 
os.kill(newpid, signal.SIGKILL) ##Kills the pid and closes Preview

这个答案看起来很脆弱,但它对我有用。我刚刚开始学习pids,所以如果有人能提供一些知识,我将不胜感激。