web-dev-qa-db-ja.com

pythonを使用してコンピューター(Linux)をシャットダウンする

コマンドでいくつかの要件が満たされた場合にコンピューターをシャットダウンするスクリプトを作成しようとしています

    os.system("poweroff")

また試した

    os.system("shutdown now -h")

その他いくつか。しかし、実行しても何も起こりません。コンピューターはクラッシュせず、エラーメッセージを生成せずにコードを処理し、コンピューターをシャットダウンせずにスクリプトを正常に終了します。

Pythonでコンピュータをシャットダウンするにはどうすればよいですか?

編集:

私が試したコマンドにはルートアクセスが必要なようです。昇格した権限なしでスクリプトからマシンをシャットダウンする方法はありますか?

15
user3522859

そこにあるLinuxディストリビューションの多くは、shutdownまたはhaltを実行するためにスーパーユーザー権限を必要としますが、コンピューターに座っている場合、rootにならずに電源を切ることができます。メニューを開いてShutdownを押すと、rootにならずにシャットダウンしますか?

まあ... rationaleこの背後にあるのは、コンピューターに物理的にアクセスできる場合は、電源コードを抜いて電源を切ることができるため、最近では多くのディストリビューションで電源オフが許可されていますがdbusを介してアクセス可能なローカルシステムバスへのアクセス。 dbus(またはそれを介して公開されるサービス)に問題がありますか?それは常に変化しています。 D-feet などのdbusビューアツールをインストールすることをお勧めします(なお、視覚化するのはかなり難しいですが、役立つかもしれません)

これらの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:

私は少し研究を行ってきましたが、これは ConsoleKit を介して新しいUbuntuバージョンで行われているようです。 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:

おそらくwhyrootでなくてもこれを実行できますか?少し広い説明に値します。新しい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は単なるメッセージパッシングシステムです。インターフェースをd-busに公開するConsoleKitなどのサービスがあります。公開されているメソッドの1つはStop(上記を参照)です。 ConsoleKitの許可はPolKitで制御されます。これは(通常のLinux許可に基づいているにも関わらず)"who何ができるか]。たとえば、PolKitは次のように言うことができます"ユーザーがコンピューターにログインしている場合、ユーザーに何かを許可します。リモートで接続している場合は許可しません。"PolKitが、ユーザーがConsoleKitStopメソッドの呼び出しを許可されていると判断した場合、その要求は(またはthrough =)d-busからConsoleKit(これは後でコンピュータをシャットダウンします...価値があるため... rootであるため)

参考文献:

要約すると:rootでなければ、コンピューターのスイッチを切ることはできません。ただし、rootとして実行されているサービスにシステムをシャットダウンするよう指示することができます。

[〜#〜]ボーナス[〜#〜]

私はあなたのコメントの1つを読んで、あなたはそれが過熱するのを防ぐために時間のかかる仕事の後にコンピュータのスイッチを切りたいと思います...あなたができることを知っていましたおそらく RTCを使用して与えられた時間に電源を入れます? ( this および this を参照) (これができるとわかったとき、私はとても興奮しました...):-D

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

root権限でスクリプトを実行します。

20
Rahul R Dhobi

システムをシャットダウンする最良の方法は、次のコードを使用することです

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

Logind(新しいFedoraシステム)を使用している場合の@BorrajaXの回答に追加するだけです:

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

特権を上げずにシャットダウンする方法はありますか?

いいえ、ありません(残念!)。

いくつかのシステム機能を使用して、通常のユーザーの権限昇格を簡単にすることができることに留意してください。

2
Brian Cain

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)
0
Ali Nemati
import os
os.system("shutdown now -h")

実行:Sudo python_script.py


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

実行:$ python_script.py # no Sudo required

0
Javi