繁体   English   中英

为什么这个python脚本只能在Ubuntu 12.04上使用IDLE?

[英]Why does this python script only work from IDLE on Ubuntu 12.04?

编辑 用C写的它就像一个冠军。 我开始注意到python会无法预测地失败。 bash解决方案也有效,但我希望能够轻松检查它是否正在运行所以我编写了C版本,所以当我做ps -e时我可以看到它。

为了解决这个问题真正的问题 (VLC播放器在播放结束后继续禁止电源管理守护进程)我编写了以下脚本。 当我从IDLE运行它而不是从终端运行时,它可以工作。 我的最终目标是将此脚本作为启动应用程序运行。 我正在使用Ubuntu 12.04和Python 2.7.3。 我需要改变什么来达到预期的效果? 请原谅我的业余蟒蛇技能。 提前致谢

编辑:脚本在终端运行,因为我拿出了t.daemon = True (感谢Max Noel)但是脚本仍然没有使用命令python /path/to/script/vlc_watchdog.py和我运行作为启动应用程序运行注意到当它从终端运行时,只有终端窗口保持打开才能工作。 即使父母被关闭/被杀之后,我希望这个过程能够流下来并且快乐且自由并且独立于它的父母。 我该如何做到这一点?

什么几乎工作: sudo apt-get install python-daemon ; import daemon添加到脚本中; import time移到顶部并立即添加time.sleep(30) ; 取消所有线程的东西,并在其中放置with daemon.DaemonContext(): run() ; 在Ubuntu 12.04的Startup Applications窗口中添加一个执行命令python /path/to/script/vlc_watchdog_daemon.py &的条目。 那个&最后很重要。 最好的猜测 (我在Ubuntu和Python上都是n00b)是有些东西没有完全加载,而且这种不完全加载的情况导致脚本行为异常。 这就是为什么我在import time立即添加了sleep并在启动应用程序命令的末尾添加了& 我可能已经开始做更少的事情,但在头痛之后,我正处于“它的工作没有触及它!!!”的地步。 有可能删除“修复”并仍然可以使其工作。 欢迎读者试试。 我很好。 最终版本的脚本在问题结束时。

原始版本没有作为启动脚本工作,但从IDLE和终端工作:

#vlc_watchdog.py  version 0.1
import dbus
import os
import time
import subprocess
from subprocess import Popen, PIPE
from threading import Thread

def vlc_killer():
    bus = dbus.SessionBus()
    vlc_media_player_obj = bus.get_object("org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2")
    props_iface = dbus.Interface(vlc_media_player_obj, 'org.freedesktop.DBus.Properties')
    pb_stat = props_iface.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')
    if pb_stat == 'Stopped':
        os.system("kill -9 $(pidof vlc)")

def vlc_is_running():
    ps = subprocess.Popen(['ps', '-e'], stdout = PIPE)
    out, err = ps.communicate()
    for line in out.splitlines():
        if 'vlc' in line:
            return True
    return False

def run():
    while True:
        if vlc_is_running():
            vlc_killer()
        else:
            time.sleep(30)

t = Thread(target=run)
#t.daemon = True  <-- this is what broke it.  Thanks Max Noel
t.start()

最终版本按预期工作:

#!/usr/bin/env python
import time
time.sleep(30)
import dbus
import os
import subprocess
from subprocess import Popen, PIPE
import daemon
import setproctitle

sleeptime = 15

def vlc_killer():
    bus = dbus.SessionBus()
    vlc_media_player_obj = bus.get_object("org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2")
    props_iface = dbus.Interface(vlc_media_player_obj, 'org.freedesktop.DBus.Properties')
    pb_stat = props_iface.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')
    if pb_stat == 'Stopped':
        os.system("kill -9 $(pidof vlc)")
    else:
        time.sleep(sleeptime)

def vlc_is_running():
    ps = subprocess.Popen(['ps', '-e'], stdout = PIPE)
    out, err = ps.communicate()
    for line in out.splitlines():
        if 'vlc' in line:
            return True
    return False

def run():
    setproctitle.setproctitle('vlc-watchdog')
    while True:
        if vlc_is_running():
            vlc_killer()
        else:
            time.sleep(sleeptime)

with daemon.DaemonContext():
    run()

在启动时通过将python /path/to/script/vlc_watchdog_daemon.py &添加到Ubuntu 12.04中的启动应用程序窗口来执行。 有关详细说明,请参阅添加启动应用程序 我正在运行Python 2.7.3。

你的线程有daemon = True 只要运行的唯一线程是守护线程,您的Python程序就会终止(请参阅http://docs.python.org/2/library/threading.html#thread-objects )。

所以发生的事情是,在你的t.start()调用发生的确切时刻,你的主线程到达终点。 Python VM检查剩下的线程是什么,只查找t ,这是守护进程,并在不执行run方法中的任何代码的情况下终止。

IDLE在IDLE中运行的原因是IDLE在自己的Python进程中运行Python代码,而不是生成一个新代码。 所以当你到达代码的末尾时,Python VM会检查剩下的线程,找到很多线程(非守护进程),因为整个IDE仍在内部并且不会终止,因此你的代码会继续运行并杀死VLC。

此外,我认为你的代码不需要在一个单独的线程中运行(你的主线程,毕竟什么都不做)。 完全取消它,并让你的看门狗程序只是循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM