2014-04-11 20 views
7

Sto cercando di scrivere uno script che vi spegnere il computer se alcuni requisiti sono riempiti con il comandospegnimento del computer (Linux) utilizzando python

os.system("poweroff") 

anche cercato

os.system("shutdown now -h") 

e pochi altri. ma non succede niente quando lo eseguo, il computer passa attraverso il codice senza crash o produce messaggi di errore e termina normalmente lo script, senza spegnere il computer.

Come si spegne il computer in python?

modifica:

Sembra che i comandi ho provato richiede accesso root. C'è un modo per spegnere la macchina dallo script senza privilegi elevati?

+2

'poweroff' e' shutdown' richiedono i privilegi. Quale utente stai usando per eseguire lo script? – fedorqui

+0

L'ho eseguito come un "utente normale" ... grazie, modificherò la domanda per riflettere che la soluzione dovrebbe funzionare senza accesso root – user3522859

+0

Non è possibile arrestare il sistema con i normali privilegi dell'utente. Qual è il tuo obiettivo finale? – Joni

risposta

14

Molte delle distribuzioni Linux fuori ci richiedono privilegi di super utente per eseguire shutdown o halt, ma poi, come c che se sei seduto sul tuo computer puoi spegnerlo senza essere root? Bene ... l'idea alla base di questo è che se si ha accesso fisico al computer, si potrebbe praticamente tirare il cavo di alimentazione e spegnerlo comunque, quindi oggi molte distribuzioni consentono lo spegnimento tramite l'accesso al bus di sistema locale accessibile attraverso dbus. Problema con dbus (o i servizi esposti attraverso di esso, piuttosto)? È in continua evoluzione. Mi consiglia di installare uno strumento visualizzatore dbus come D-feet (attenzione: è ancora piuttosto difficile da visualizzare, ma può essere d'aiuto)

Dai uno sguardo a these Dbus shutdown scripts.

Se avete ancora HAL in distrubuzione (è sulla buona strada per essere deprecato) provate questo:

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

Questo funziona su un'Ubuntu 12.04 (ho appena alimentato il mio computer per assicurarsi che ha funzionato) . Se hai qualcosa di più nuovo ... beh, potrebbe non funzionare. È il lato negativo di questo metodo: è molto specifico per la distribuzione.

Potrebbe essere necessario installare il pacchetto dbus-python per questo al lavoro (http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html)

UPDATE 1:

ho fatto un po 'di ricerca e sembra che questo è fatto in versioni più recenti di Ubuntu tramite ConsoleKit. Ho provato il codice qui sotto nel mio Ubuntu 12.04 (che ha la HAL deprecato e il più recente ConsoleKit) ed ho chiuso il mio computer spento:

>>> 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:

Probabilmente perché puoi fare questo senza essere root merita una spiegazione un po 'più ampia. Concentriamoci sul nuovo ConsoleKit (HAL è molto più complicato e disordinato, IMHO).

Il ConsoleKit è un servizio in esecuzione come root nel sistema:

[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 

Ora, d-bus è solo un sistema di passaggio dei messaggi. Hai un servizio, ad esempio ConsoleKit che espone un'interfaccia a d-bus. Uno dei metodi esposti è lo Stop (mostrato sopra). Le autorizzazioni di ConsoleKit sono controllate con PolKit, che (nonostante sia basato su permessi Linux regolari) offre un po 'più fine controllo per "chi può fare cosa". Ad esempio, PolKit può dire cose come "Se l'utente è connesso al computer, quindi permettergli di fare qualcosa, se è connesso in remoto, allora non farlo".. Se polkit determina che l'utente è autorizzato a chiamare il metodo ConsoleKit s' Stop, tale richiesta sarà approvata dal (o attraverso) d-bus-ConsoleKit (che sarà successivamente spegnere il computer perché può ... perché la pena è tutto ... perché è root)

Ulteriori approfondimenti:

Per riepilogare: non è possibile spegnere un computer senza essere root. Ma puoi dire a un servizio che funziona come root di spegnere il sistema per te.

BONUS:

ho letto in uno dei vostri commenti che tu voglia spegnere il computer dopo un compito che richiede tempo per evitare il surriscaldamento ... Lo sapevate che si può probabilmente potere che attivo in un determinato momento utilizzando RTC? (Vedi this e this) Molto carino, eh?(Mi sono così emozionato quando ho scoperto che potevo farlo ...) :-D

+0

OT: Quel "piuttosto bello , eh? " è familiare, non è vero? – edmz

+2

@black: vieni di nuovo? * familiare * come non troppo serio? Se è così, allora si. La programmazione è divertente! E emozionante !!! E cool **: -) ** – BorrajaX

+1

Mi riferivo a DaveHax in realtà. Nessun problema – edmz

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

esegue lo script con i privilegi di root.

2

un modo per chiudere ... senza privilegi elevati?

No, non c'è (per fortuna!).

Tenete a mente che è possibile utilizzare diverse funzioni del sistema di fare escalation dei privilegi per gli utenti normali facile:

0

Sto usando Fedora e funziona con me. tutto ciò che devo fare è scrivere questa riga nel terminale:

$ sudo python yourScript.py 
-1

C'è un modo per spegnere il computer senza utilizzare autorizzazioni elevate.

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

osascript non è linux –

+0

ahh, scusa sono ancora nuovo a questo: D – RyanKramer

1

Giusto per aggiungere alla risposta @BorrajaX s' per coloro che utilizzano logind (sistemi più recenti 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

Il modo migliore per spegnere il sistema è quello di utilizzare i seguenti codici

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

Questo funziona solo se stai usando systemd. Non tutte le distribuzioni di Linux hanno questo. –

Problemi correlati