我正在尝试编写一个脚本,如果命令满足一些要求,它将关闭计算机
os.system("poweroff")
也试过
os.system("shutdown now -h")
和其他一些人。但是当我运行它时没有任何反应,计算机通过代码而不会崩溃或产生任何错误消息并正常终止脚本,而不会关闭计算机。
如何在 python 中关闭计算机?
编辑:
似乎我尝试过的命令需要root访问权限。有没有办法在没有提升权限的情况下从脚本关闭机器?
我正在尝试编写一个脚本,如果命令满足一些要求,它将关闭计算机
os.system("poweroff")
也试过
os.system("shutdown now -h")
和其他一些人。但是当我运行它时没有任何反应,计算机通过代码而不会崩溃或产生任何错误消息并正常终止脚本,而不会关闭计算机。
如何在 python 中关闭计算机?
编辑:
似乎我尝试过的命令需要root访问权限。有没有办法在没有提升权限的情况下从脚本关闭机器?
import os
os.system("shutdown now -h")
以 root 权限执行您的脚本。
那里的许多 linux 发行版都需要超级用户权限才能执行shutdown
or halt
,但是,如果您坐在计算机上,为什么无需 root 就可以关闭它?你打开一个菜单,点击Shutdown,它会自动关机root
,对吧?
嗯......这背后的基本原理是,如果您可以物理访问计算机,则几乎可以拉电源线并将其关闭电源,因此,如今,许多发行版都允许关闭电源,尽管可以访问本地系统总线通过dbus
. 问题dbus
(或者通过它暴露的服务,而是)?它在不断变化。我建议安装一个 dbus 查看器工具,例如D-feet(请注意:它仍然很难可视化,但它可能会有所帮助)
看看这些 Dbus 关闭脚本。
如果您的分发中仍有 HAL(即将被弃用),请尝试以下操作:
import dbus
sys_bus = dbus.SystemBus()
hal_srvc = sys_bus.get_object('org.freedesktop.Hal',
'/org/freedesktop/Hal/devices/computer')
pwr_mgmt = dbus.Interface(hal_srvc,
'org.freedesktop.Hal.Device.SystemPowerManagement')
shutdown_method = pwr_mgmt.get_dbus_method("Shutdown")
shutdown_method()
这适用于 Ubuntu 12.04(我刚刚关闭计算机以确保它正常工作)。如果你有更新的东西......好吧,它可能无法正常工作。这是这种方法的缺点:它是非常特定于分布的。
您可能必须安装该dbus-python
软件包才能使其正常工作(http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html)
更新 1:
我一直在做一些研究,看起来这是通过ConsoleKit在较新的 Ubuntu 版本中完成的。我已经在我的 Ubuntu 12.04(它具有已弃用的 HAL 和更新的 ConsoleKit)中测试了以下代码,它确实关闭了我的计算机:
>>> import dbus
>>> sys_bus = dbus.SystemBus()
>>> ck_srv = sys_bus.get_object('org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager')
>>> ck_iface = dbus.Interface(ck_srv, 'org.freedesktop.ConsoleKit.Manager')
>>> stop_method = ck_iface.get_dbus_method("Stop")
>>> stop_method()
更新 2:
可能为什么你可以做到这一点而不root
值得更广泛的解释。让我们关注更新的ConsoleKit
(HAL
更复杂和混乱,恕我直言)。
这ConsoleKit
是root
在您的系统中运行的服务:
borrajax@borrajax:/tmp$ ps aux|grep console-kit
root 1590 0.0 0.0 1043056 3876 ? Sl Dec05 0:00 /usr/sbin/console-kit-daemon --no-daemon
现在,d-bus
只是一个消息传递系统。您有一个服务,例如ConsoleKit,它向d-bus
. 暴露的方法之一是Stop
(如上所示)。ConsoleKit的权限由PolKit控制,它(尽管基于常规的 Linux 权限)为“谁可以做什么”提供了更精细的控制。例如,PolKit可以说“如果用户登录到计算机,则允许他做某事。如果它是远程连接的,则不要”。. 如果PolKit确定您的用户可以调用ConsoleKit的Stop
方法,该请求将通过(或通过)传递d-bus
给ConsoleKit(随后将关闭您的计算机,因为它可以......因为它值得......因为它是root
)
进一步阅读:
总结一下:你不能在没有root
. 但是您可以告诉正在运行的服务root
为您关闭系统。
更新 3:
2021 年 12 月,在最初的答案写完七年后,我不得不再次这样做。这一次,在 Ubuntu 18.04 中。
不出所料,事情似乎发生了一些变化:
org.freedesktop.login1
服务处理的,该服务是“”“新”“” (咳!咳!) SystemD机器的一部分。dbus
似乎已被弃用和/或被视为“遗留”。但是,可以使用一个新的PyDbus 库来代替。所以我们仍然可以使用非特权脚本关闭机器:
#! /usr/bin/python3
from pydbus import SystemBus
bus = SystemBus()
proxy = bus.get('org.freedesktop.login1', '/org/freedesktop/login1')
if proxy.CanPowerOff() == 'yes':
proxy.PowerOff(False) # False for 'NOT interactive'
更新 3.1:
好像没有我想的那么新XD
@Roeften 在同一个线程中已经给出了答案。
奖金:
我在您的一条评论中读到,您想在完成一项耗时的任务后关闭计算机以防止其过热……您知道您可以在给定的时间使用 RTC 打开它吗?(看到这个和这个)很酷,嗯?(当我发现我可以做到这一点时,我非常兴奋......):- D
关闭系统的最佳方法是使用以下代码
import os
os.system('systemctl poweroff')
只是为使用 logind(较新的 Fedora 系统)的人添加 @BorrajaX 的答案:
import dbus
sys_bus = dbus.SystemBus()
lg = sys_bus.get_object('org.freedesktop.login1','/org/freedesktop/login1')
pwr_mgmt = dbus.Interface(lg,'org.freedesktop.login1.Manager')
shutdown_method = pwr_mgmt.get_dbus_method("PowerOff")
shutdown_method(True)
linux:
import subprocess
cmdCommand = "shutdown -h now"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)
视窗:
import subprocess
cmdCommand = "shutdown -s"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)
import os
os.system("shutdown now -h")
执行: sudo python_script.py
import subprocess
import shlex
cmd = shlex.split("sudo shutdown -h now")
subprocess.call(cmd)
执行: $ python_script.py # no sudo required
试试这个
import os
os.system("sudo shutdown now -h")
这对我有用
我正在使用 Fedora,它适用于我。我需要做的就是在终端中写下这一行:
$ sudo python yourScript.py
有一种方法可以在不使用提升权限的情况下关闭计算机。
import os
subprocess.call(['osascript', '-e', 'tell app "system events" to shut down'])