2014-04-11 30 views
7

Próbuję napisać skrypt, który zostanie wyłączony komputer, jeśli kilka wymagania są wypełnione poleceniawyłączania komputera (Linux) przy użyciu Pythona

os.system("poweroff") 

próbował również

os.system("shutdown now -h") 

i kilka innych. ale po uruchomieniu komputera nic się nie dzieje, komputer przechodzi przez kod bez awarii lub generowania komunikatów o błędach i normalnie kończy działanie skryptu, bez wyłączania komputera.

Jak można wyłączyć komputer w pythonie?

edit:

Wydaje się, że polecenia próbowałem wymaga dostępu root. Czy istnieje sposób na wyłączenie komputera ze skryptu bez podwyższonych uprawnień?

+2

'poweroff' i' shutdown' wymaga uprawnień. Który użytkownik używasz do wykonania skryptu? – fedorqui

+0

Używam go jako "zwykłego użytkownika" ... dzięki, edytuje pytanie, aby odzwierciedlić, że rozwiązanie powinno działać bez dostępu do roota – user3522859

+0

Nie można zamknąć systemu przy użyciu zwykłych uprawnień użytkownika. Jaki jest twój ostateczny cel? – Joni

Odpowiedz

14

Wiele dystrybucjach linuksa out wymagane są uprawnienia superużytkownika do wykonania shutdown lub halt, ale Czy to, że siedzisz na komputerze, możesz go wyłączyć, nie będąc rooterem? No cóż ... chodzi o to, że jeśli masz fizyczny dostęp do komputera, możesz w zasadzie pociągnąć za przewód zasilający i go wyłączyć, tak więc obecnie wiele dystrybucji pozwala na wyłączenie, chociaż dostęp do lokalnej magistrali systemowej jest możliwy przez dbus. Problem z dbus (czy raczej z usługami przez nie wystawionymi)? Ciągle się zmienia. Zalecam zainstalowanie narzędzia przeglądarki dbus, takiego jak D-feet (uwaga: nadal jest to dość trudne do wizualizacji, ale może pomóc)

Zobacz, jak wygląda these Dbus shutdown scripts.

Jeśli nadal masz HAL w swojej numeru: (jest w drodze do wycofywana) spróbuj tego:

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() 

To działa na Ubuntu 12.04 (po prostu wyłączony komputer, aby upewnić się, że pracował) . Jeśli masz coś nowszego ... cóż, to może nie działać. To jest wadą tej metody: jest bardzo specyficzna dla dystrybucji.

Być może trzeba zainstalować pakiet dbus-python dla tej pracy (http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html)

UPDATE 1:

Robiłem trochę badań i wygląda jak odbywa się to w nowsze wersje Ubuntu do ConsoleKit. Przetestowałem poniższy kod w moim Ubuntu 12.04 (który ma przestarzałe HAL i nowszą ConsoleKit) i to nie mój komputer się wyłączy:

>>> 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() 

UPDATE 2:

Prawdopodobnie dlaczego możesz to zrobić bez bycia root zasługuje na nieco szersze wyjaśnienie. Skupmy się na nowszym ConsoleKit (HAL jest o wiele bardziej skomplikowany i brudny, IMHO).

The ConsoleKit to serwis działa jako root w systemie:

[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 

Teraz d-bus jest tylko system przekazując wiadomość. Masz usługę, taką jak ConsoleKit, która udostępnia interfejs do d-bus. Jedną z ujawnionych metod jest Stop (przedstawiony powyżej). Uprawnienia do konsoli ConsoleKit są kontrolowane za pomocą PolKit, która (pomimo tego, że opiera się na zwykłych uprawnieniach Linuksa) oferuje nieco lepsze ziarno kontroli dla "kto może zrobić co". Na przykład: PolKit może powiedzieć takie rzeczy, jak "Jeśli użytkownik jest zalogowany na komputerze, pozwól mu coś zrobić. Jeśli jest zdalnie podłączony, to nie".. Jeśli polkit określa, czy użytkownik może zadzwonić Stop metodę ConsoleKit „s, że prośba zostanie przekazana przez (lub przez) d-bus do ConsoleKit (które następnie wyłączenie komputera, ponieważ może ... dlatego warto jest to ... bo to root)

Dalsze czytanie:

Podsumowując: Nie można wyłączyć komputera, nie będąc root. Ale możesz powiedzieć usługi, która działa jako root, aby zamknąć system dla ciebie.

BONUS:

czytałem w jednym ze swoich komentarzy, które chcesz przełączać komputer wyłącza się po to czasochłonne zadanie, aby zapobiec przed przegrzaniem ... Czy wiesz, że można prawdopodobnie Power IT w danym czasie przy użyciu RTC? (Patrz this i this) Całkiem fajnie, uh?(Byłem tak podekscytowany, gdy dowiedziałem się, że mogę to zrobić ...) :-D

+0

OT: To "całkiem fajne" , uh? " jest znany, prawda? – edmz

+2

@black: Chodź jeszcze raz? * znajomy * jako niezbyt poważny? Jeśli tak, to tak. Programowanie jest fajne! I ekscytujące!!! I fajnie **: -) ** – BorrajaX

+1

Miałem na myśli DaveHax. Bez obaw – edmz

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

wykonać skrypt z uprawnieniami użytkownika root.

2

jakikolwiek sposób na zamknięcie ... bez podwyższonych uprawnień?

Nie, nie ma (na szczęście!).

Należy pamiętać, że można wykorzystać kilka funkcji systemowych, aby przekroczenia uprawnień dla zwykłych użytkowników prościej

0

Używam Fedory i działa ze mną. wszystko, co muszę zrobić, to Zapisanie tej linii na terminalu:

$ sudo python yourScript.py 
-1

Istnieje sposób na wyłączenie komputera bez podwyższonych uprawnień.

import os 
subprocess.call(['osascript', '-e', 'tell app "system events" to shut down']) 
+0

osascript nie jest linuxem –

+0

ahh, przepraszam Jestem wciąż nowy: D – RyanKramer

1

Wystarczy dodać do odpowiedzi @BorrajaX jest dla osób korzystających logind (nowsze systemy 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) 
1

Najlepszym sposobem na zamknięcie systemu jest zastosowanie następujące kody

import os 
os.system('systemctl poweroff') 
+0

Działa to tylko, jeśli używasz systemd. Nie wszystkie dystrybucje linuksowe mają to. –

Powiązane problemy