Выключение компьютера (Linux) с помощью Python

Я пытаюсь написать сценарий, который выключит компьютер, если команда выполнит несколько требований

    os.system("poweroff")

также пытался

    os.system("shutdown now -h")

и несколько других. но ничего не происходит, когда я запускаю его, компьютер проходит код без сбоев или выдачи каких-либо сообщений об ошибках и обычно завершает работу сценария, не выключая компьютер.

Как отключить компьютер в python?

редактировать:

Кажется, что команды, которые я попробовал, требуют root-доступа. Есть ли способ выключить машину из скрипта без повышенных привилегий?

10 ответов

Решение

Во многих дистрибутивах Linux для выполнения требуются привилегии суперпользователя. shutdown или же haltНо почему же, если вы сидите за своим компьютером, вы можете выключить его, не будучи пользователем root? Ну... идея заключается в том, что если у вас есть физический доступ к компьютеру, вы можете в значительной степени отключить шнур питания и отключить его в любом случае, поэтому в настоящее время многие дистрибутивы позволяют отключать питание, хотя доступ к локальной системной шине доступен через dbus, Проблема с dbus (или сервисы, выставленные через него, скорее)? Это постоянно меняется. Я бы порекомендовал установить средство просмотра dbus, такое как D-foot (имейте в виду: это все еще довольно сложно визуализировать, но это может помочь)

Посмотрите на эти сценарии выключения 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:

Я провел небольшое исследование, и похоже, что это делается в более новых версиях Ubuntu через ConsoleKit. Я протестировал приведенный ниже код в своей 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 отключить систему для вас.

БОНУС:

Я прочитал в одном из ваших комментариев, что вы хотите выключить компьютер после трудоемкой задачи, чтобы предотвратить его перегрев... Знаете ли вы, что, возможно, вы можете включить его в определенное время, используя RTC? (Смотрите это и это) Довольно круто, а? (Я так обрадовался, когда узнал, что могу это сделать...) :-D

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

Запустите ваш скрипт с правами суперпользователя.

Лучший способ выключить систему - использовать следующие коды

import os
os.system('systemctl poweroff') 

Просто добавьте ответ @BorrajaX для тех, кто использует logind (более новые системы 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)

любой способ закрыть... без повышенных привилегий?

Нет, нет (к счастью!)

Помните, что вы можете использовать несколько системных функций, чтобы упростить повышение привилегий для обычных пользователей:

  • sudo
  • setuid
  • setcap

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)
Если вы хотите выполнить его от root, ответ @Rahul R Dhobi прекрасно работает:
import os
os.system("shutdown now -h")

Исполнение: sudo python_script.py


Если вам нужно выполнить его без прав root:
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'])
Другие вопросы по тегам