La meilleure façon d'arrêter un système est d'utiliser les codes suivants
import os
os.system('systemctl poweroff')
De nombreuses distributions Linux nécessitent des privilèges de super utilisateur pour exécuter shutdown
ou halt
, mais alors, comment se fait-il que si vous êtes assis sur votre ordinateur, vous pouvez l'éteindre sans être root ? Vous ouvrez un menu, appuyez sur Arrêter et il s'arrête sans que vous deveniez root
, n'est-ce pas ?
Eh bien... la justification derrière cela est que si vous avez un accès physique à l'ordinateur, vous pouvez à peu près tirer le cordon d'alimentation et l'éteindre de toute façon, donc de nos jours, de nombreuses distributions permettent la mise hors tension via l'accès au bus système local accessible via dbus
. Problème avec dbus
(ou les services qui y sont exposés, plutôt) ? C'est en constante évolution. Je recommanderais d'installer un outil de visualisation dbus tel que D-feet (attention :c'est encore assez difficile à visualiser, mais cela peut aider)
Jetez un œil à ces scripts d'arrêt Dbus.
Si vous avez toujours HAL dans votre distribution (est sur le point d'être obsolète), essayez ceci :
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()
Cela fonctionne sur un Ubuntu 12.04 (je viens d'éteindre mon ordinateur pour m'assurer qu'il fonctionnait). Si vous avez quelque chose de plus récent... eh bien, cela peut ne pas fonctionner. C'est l'inconvénient de cette méthode :elle est très spécifique à la distribution.
Vous devrez peut-être installer le dbus-python
package pour que cela fonctionne (http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html)
MISE À JOUR 1 :
J'ai fait un peu de recherche et il semble que cela se fasse dans les nouvelles versions d'Ubuntu via ConsoleKit. J'ai testé le code ci-dessous dans mon Ubuntu 12.04 (qui a le HAL obsolète et le nouveau ConsoleKit) et il a éteint mon ordinateur :
>>> 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()
MISE À JOUR 2 :
Probablement pourquoi pouvez-vous le faire sans être root
mérite une explication un peu plus large. Concentrons-nous sur le nouveau ConsoleKit
(HAL
est beaucoup plus compliqué et désordonné, à mon humble avis).
Le ConsoleKit
est un service exécuté en tant que root
dans votre système :
[email protected]:/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
Maintenant, d-bus
est juste un système de transmission de messages. Vous avez un service, tel que ConsoleKit qui expose une interface à d-bus
. L'une des méthodes exposées est le Stop
(montré ci-dessus). Kit de console les permissions de sont contrôlées avec PolKit , qui (bien qu'il soit basé sur les autorisations Linux habituelles) offre un contrôle un peu plus fin pour "qui peut faire quoi" . Par exemple, PolKit peut dire des choses comme "Si l'utilisateur est connecté à l'ordinateur, alors autorisez-le à faire quelque chose. S'il est connecté à distance, alors ne le faites pas." . Si PolKit détermine que votre utilisateur est autorisé à appeler ConsoleKit est Stop
méthode, cette requête sera transmise par (ou via ) d-bus
vers ConsoleKit (ce qui éteindra ensuite votre ordinateur parce qu'il peut... parce que ça vaut le coup... parce que c'est root
)
Lectures complémentaires :
- Qu'est-ce que ConsoleKit et PolicyKit ? Comment fonctionnent-ils ?
- ArchWiki PolKit
Pour résumer :Vous ne pouvez pas éteindre un ordinateur sans être root
. Mais vous pouvez dire à un service qui s'exécute en tant que root
pour arrêter le système pour vous.
MISE À JOUR 3 :
En décembre 2021, sept ans après la rédaction de la réponse originale, j'ai dû le refaire. Cette fois, dans un Ubuntu 18.04.
Sans surprise, les choses semblent avoir un peu changé :
- La fonctionnalité PowerOff semble être gérée via un nouveau
org.freedesktop.login1
service, qui fait partie du """nouveau""" (toux ! toussez !) Machines SystemD . - Le
dbus
Le package Python semble avoir été obsolète et/ou considéré comme "hérité". Il existe cependant une nouvelle bibliothèque PyDbus à utiliser à la place.
Nous pouvons donc toujours éteindre les machines avec un script non privilégié :
#! /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'
Mise à jour 3.1 :
On dirait qu'il n'est pas comme neuf comme je le pensais X-D
Il y a déjà une réponse de @Roeften dans ce même fil.
BONUS :
J'ai lu dans l'un de vos commentaires que vous souhaitiez éteindre l'ordinateur après une tâche fastidieuse pour éviter qu'il ne surchauffe... Saviez-vous que vous pouvez probablement l'allumer à un moment donné en utilisant RTC ? (Voir ça et ça) Plutôt cool, hein ? (J'étais tellement excité quand j'ai découvert que je pouvais faire ça... ) :-D
import os
os.system("shutdown now -h")
exécutez votre script avec les privilèges root.
un moyen d'arrêter... sans privilèges élevés ?
Non, il n'y en a pas (heureusement !).
Gardez à l'esprit que vous pouvez utiliser plusieurs fonctionnalités du système pour faciliter l'élévation des privilèges pour les utilisateurs normaux :
sudo
setuid
setcap