编辑 Written in C它就像一个冠军。我开始注意到python会无法预测地失败。 The bash solution也有效,但我希望能够轻松检查它是否正在运行所以我编写了C版本,以便在我ps -e
时看到它。
尝试解决this issue和the real problem(VLC播放器在播放结束后继续禁止电源管理守护程序)我编写了以下脚本。当我从IDLE运行它而不是从终端运行时,它可以工作。我的最终目标是将此脚本作为启动应用程序运行。我正在使用Ubuntu 12.04和Python 2.7.3。我需要改变什么来达到预期的效果?请原谅我的业余蟒蛇技能。提前致谢
编辑:自从我拿出t.daemon = True
后,脚本在终端中运行(感谢Max Noel)但是脚本仍然不能使用命令startup application运行{ {1}}并且我注意到当它从终端运行时,只有终端窗口保持打开才能工作。即使父母被关闭/被杀之后,我希望这个过程能够流下来并且快乐且自由并且独立于它的父母。我该如何做到这一点?
几乎有效: python /path/to/script/vlc_watchdog.py
;将sudo apt-get install python-daemon
添加到脚本中;将import daemon
移至顶部,然后立即添加import time
;取消所有线程的东西,放在time.sleep(30)
;在Ubuntu 12.04的Startup Applications窗口中添加一个执行命令with daemon.DaemonContext(): run()
的条目。最后python /path/to/script/vlc_watchdog_daemon.py &
很重要。我的最佳猜测(我在Ubuntu和Python上都是n00b)是有些东西没有完全加载,这个不完全加载的条件导致了脚本行为异常。这就是我在&
之后立即添加sleep
并在Startup Applications命令末尾添加import time
的原因。我可能已经开始做更少的事情,但在头痛之后,我正处于“它的工作没有触及它!!!”的地步。有可能删除“修复”并仍然可以使其工作。欢迎读者试试。我很好。 问题末尾的最终脚本版本。
原始版本没有作为启动脚本工作,但是从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()
添加到Ubuntu 12.04中的“启动应用程序”窗口来执行。有关详细说明,请参阅Adding Startup Applications。我正在运行Python 2.7.3。
答案 0 :(得分: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。
此外,我认为你的代码不需要在一个单独的线程中运行(你的主线程,毕竟什么都不做)。完全取消它,并让你的看门狗程序只是循环。