本文介绍了如何杀死通过 Python 启动的无头 X 服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 Python 获取网页的屏幕截图.为此,我使用 http://github.com/AdamN/python-webkit2png/.

I want to get screenshots of a webpage in Python. For this I am using http://github.com/AdamN/python-webkit2png/ .

    newArgs = ["xvfb-run", "--server-args=-screen 0, 640x480x24", sys.argv[0]]
    for i in range(1, len(sys.argv)):
        if sys.argv[i] not in ["-x", "--xvfb"]:
            newArgs.append(sys.argv[i])
    logging.debug("Executing %s" % " ".join(newArgs))
    os.execvp(newArgs[0], newArgs)

基本上使用正确的参数调用 xvfb-run.但是 man xvfb 说:

Basically calls xvfb-run with the correct args. But man xvfb says:

注意,上面例子中使用的demo X客户端不会自己退出,所以在xvfb-run退出之前必须先杀死它们.

所以这意味着这个脚本将 <????>如果整个事情都在循环中,(获取多个屏幕截图)除非 X 服务器被杀死.我怎样才能做到这一点?

So that means that this script will <????> if this whole thing is in a loop, (To get multiple screenshots) unless the X server is killed. How can I do that?

推荐答案

os.execvp 状态:

这些函数都执行一个新的程序,替换当前过程;他们不回来.[..]

所以在调用os.execvp 之后,程序中的其他语句将不会被执行.您可能想要使用 subprocess.Popen 代替:

So after calling os.execvp no other statement in the program will be executed. You may want to use subprocess.Popen instead:

subprocess 模块允许您产生新进程,连接到它们输入/输出/错误管道,并获得他们的返回码.这个模块打算更换其他几个,较旧的模块和功能,例如:

使用subprocess.Popen,在虚拟framebuffer X服务器中运行xlogo的代码变为:

Using subprocess.Popen, the code to run xlogo in the virtual framebuffer X server becomes:

import subprocess
xvfb_args = ['xvfb-run', '--server-args=-screen 0, 640x480x24', 'xlogo']
process = subprocess.Popen(xvfb_args)

现在的问题是 xvfb-run 在后台进程中启动 Xvfb.调用 process.kill() 不会杀死 Xvfb(至少在我的机器上不会......).我一直在摆弄这个,到目前为止唯一对我有用的是:

Now the problem is that xvfb-run launches Xvfb in a background process. Calling process.kill() will not kill Xvfb (at least not on my machine...). I have been fiddling around with this a bit, and so far the only thing that works for me is:

import os
import signal
import subprocess

SERVER_NUM = 99  # 99 is the default used by xvfb-run; you can leave this out.

xvfb_args = ['xvfb-run', '--server-num=%d' % SERVER_NUM,
             '--server-args=-screen 0, 640x480x24', 'xlogo']
subprocess.Popen(xvfb_args)

# ... do whatever you want to do here...

pid = int(open('/tmp/.X%s-lock' % SERVER_NUM).read().strip())
os.kill(pid, signal.SIGINT)

所以这段代码从/tmp/.X99-lock中读取Xvfb的进程ID并向进程发送一个中断.它可以工作,但确实会时不时地产生一条错误消息(不过我想您可以忽略它).希望其他人可以提供更优雅的解决方案.干杯.

So this code reads the process ID of Xvfb from /tmp/.X99-lock and sends the process an interrupt. It works, but does yield an error message every now and then (I suppose you can ignore it, though). Hopefully somebody else can provide a more elegant solution. Cheers.

这篇关于如何杀死通过 Python 启动的无头 X 服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 12:15