【问题标题】:Close Image with subprocess使用子进程关闭图像
【发布时间】:2017-05-02 21:56:07
【问题描述】:

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

以前有人问过这个问题,但我找到的答案对我不起作用。这是我检查过的内容:

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)

【问题讨论】:

  • 我没有要检查的 Mac,但我似乎记得 open 是异步的 - 它会生成一个预览进程(或它启动的任何应用程序)并立即退出。因此,当您的 Python 代码有一秒钟 sleep'd 时,open 进程不再存在。如果是这种情况,我想您需要找到某种方法向open 启动的进程发送信号。作为测试,如果您将-W 选项传递给open(可能与-n 一起使用),那么它是否有效?
  • 感谢@DavidZ 的帮助,我有点新,我不知道如何在我的代码中包含“-W”或“-n”。我不断收到 Invalid Syntax 或 File Not Found 错误。你能给我举个例子吗?
  • 让我写一个答案。
  • 您或多或少地尝试使用 python 控制预览(在图像已经完成时关闭图像),所以这对于 mac os 来说非常具体。如果您想要一个更交叉兼容的程序,您应该使用tkinter 或类似的东西创建自己的图像查看器。

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


【解决方案1】:

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

您可以强制同步行为,即通过传递-W 选项使open 继续运行直到预览退出后,

subprocess.Popen(["open", "-W", mypath])

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

如果终止或终止open 不会终止预览,则您需要更改配置,以便在调用terminate()kill() 时将信号传递到open 的所有子进程,为此this questionthis one 可能会有所帮助,否则您必须找到一种方法来获取 Preview 的进程 ID 并直接向其发送信号,这将需要您超越 @987654342 @。我不确定最好的方法,但也许其他人可以提供一个答案来告诉你如何做。

【讨论】:

    【解决方案2】:

    我确信这是最简单的方法,但见鬼,它有效。如果有人偶然发现这一点并知道更好的方法,请告诉我。

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

    我首先打开我的终端并输入命令ps -A。这将显示所有当前打开的进程及其 ID。然后我刚刚搜索了Preview,发现了两个打开的进程。

    之前,我正在关闭列表中的第一个 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,所以如果有人能提供一些知识,我将不胜感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-19
      • 2011-12-30
      • 2016-04-14
      • 2011-12-30
      • 2014-08-27
      • 1970-01-01
      • 2021-12-06
      • 2019-07-09
      相关资源
      最近更新 更多