[英]Why does this work in Python 3 IDLE on Windows and not in the terminal on Ubuntu?
[英]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.