web-dev-qa-db-fra.com

arrêt de l'ordinateur (linux) en utilisant python

J'essaie d'écrire un script qui arrêtera l'ordinateur si quelques exigences sont remplies avec la commande

    os.system("poweroff")

a également essayé

    os.system("shutdown now -h")

et quelques autres. mais rien ne se passe lorsque je l'exécute, l'ordinateur passe par le code sans planter ni produire de messages d'erreur et termine le script normalement, sans arrêter l'ordinateur.

Comment arrête-t-on l'ordinateur en python?

éditer:

Semble que les commandes que j'ai essayées nécessitent un accès root. Existe-t-il un moyen d'arrêter la machine à partir du script sans privilèges élevés?

16
user3522859

De nombreuses distributions Linux nécessitent des privilèges de superutilisateur 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 Shutdown et il s'arrête sans que vous deveniez root, non?

Eh bien ... la raison derrière cela est que si vous avez un accès physique à l'ordinateur, vous pouvez à peu près débrancher le cordon d'alimentation et l'éteindre de toute façon, donc de nos jours, de nombreuses distributions autoriser la mise hors tension via l'accès au bus système local accessible via dbus. Un problème avec dbus (ou les services qui y sont exposés, plutôt)? Ça change constamment. Je recommanderais d'installer un outil de visualisation dbus tel que D-feet (attention: il est encore assez difficile à visualiser, mais cela peut aider)

Jetez un oeil à ces scripts d'arrêt Dbus .

Si vous avez encore HAL dans votre distrubution (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 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 la couche HAL obsolète et le plus récent 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 faire cela sans être root mérite un peu d'explication plus large. Concentrons-nous sur le plus récent ConsoleKit (HAL est beaucoup plus compliqué et désordonné, à mon humble avis).

ConsoleKit est un service fonctionnant sous la forme root dans votre système:

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

Maintenant, d-bus n'est qu'un système de transmission de messages. Vous disposez d'un service, tel que ConsoleKit qui expose une interface à d-bus. L'une des méthodes exposées est le Stop (illustré ci-dessus). ConsoleKit les autorisations sont contrôlées avec PolKit , qui (bien qu'il soit basé sur des autorisations Linux régulières) offre un peu plus de précision grain de contrôle pour "qui peut faire quoi" . Par exemple, PolKit peut dire des choses comme "Si l'utilisateur est connecté à l'ordinateur, laissez-le faire quelque chose. S'il est connecté à distance, alors ne 't. ". Si PolKit détermine que votre utilisateur est autorisé à appeler la méthode Stop de # ConsoleKit , cette demande sera transmise par (ou à ) d-bus à ConsoleKit (qui arrêtera ensuite votre ordinateur parce qu'il peut ... parce que ça vaut le coup ... parce que c'est root)

Lectures complémentaires:

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 d'arrêter le système pour vous.

Bonus [~ # ~] [~ # ~] :

J'ai lu dans l'un de vos commentaires que vous voulez éteindre l'ordinateur après une tâche longue pour l'empêcher de surchauffer ... Saviez-vous que vous pouvez probablement l'allumer à un temps donné en utilisant RTC? (Voir ceci et ceci ) Assez cool, euh? (Je suis tellement excité quand j'ai découvert que je pouvais faire ça ...) : - D

20
BorrajaX
import os
os.system("shutdown now -h")

exécutez votre script avec les privilèges root.

20
Rahul R Dhobi

La meilleure façon d'arrêter un système est d'utiliser les codes suivants

import os
os.system('systemctl poweroff') 
7
Sushin Pv

Juste pour ajouter à la réponse de @BorrajaX pour ceux qui utilisent logind (les nouveaux systèmes Fedora):

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)
2
Roeften

une façon de fermer ... 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'escalade de privilèges pour les utilisateurs normaux:

2
Brian Cain

linux:

import subprocess
cmdCommand = "shutdown -h now"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)

Les fenêtres:

import subprocess
cmdCommand = "shutdown -s"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)
0
Ali Nemati
import os
os.system("shutdown now -h")

Exécution:Sudo python_script.py


import subprocess
import shlex
cmd = shlex.split("Sudo shutdown -h now")
subprocess.call(cmd)

Exécution:$ python_script.py # no Sudo required

0
Javi