17

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

    os.system("poweroff")

も試した

    os.system("shutdown now -h")

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

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

編集:

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

4

10 に答える 10

22

shutdown世の中にある Linux ディストリビューションの多くは、またはを実行するためにスーパー ユーザー権限を必要とhaltします。メニューを開き、Shutdownを押すと、 にならずにシャットダウンしますよrootね?

ええと...これの背後にある理論的根拠は、コンピューターに物理的にアクセスできる場合、電源コードを引っ張ってとにかく電源を切ることができるということです.を通してdbusdbus(またはそれを介して公開されているサービス)に問題がありますか?それは絶えず変化しています。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:

おそらく、もう少し広い説明に値することなく、なぜこれを行うことができるのでしょうか。root新しいものに焦点を当てましょうConsoleKitHALもっと複雑で面倒です、IMHO)。

これは、システムで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。公開されているメソッドの 1 つがStop(上に示されている) です。ConsoleKitのパーミッションはPolKitで制御されます。これは (通常の Linux パーミッションに基づいているにもかかわらず) 「誰が何をできるか」をより細かく制御できます。たとえば、PolKitは、「ユーザーがコンピューターにログインしている場合は、何かを実行できるようにします。リモートで接続されている場合は、許可しないでください」などと言うことができます。. PolKitが、ユーザーがConsoleKitの呼び出しを許可されていると判断した場合Stopメソッドを使用すると、その要求はConsoleKitによって (またはを介し​​て)渡されます (その後、コンピュータがシャットダウンされます。d-busroot

参考文献:

要約すると、コンピュータの電源を切ることはできませんroot。ただし、実行中のサービスrootにシステムをシャットダウンするように指示することはできます。

更新 3:

元の回答が書かれてから 7 年後の 2021 年 12 月、私はこれをやり直さなければなりませんでした。今回は、Ubuntu 18.04 で。

当然のことながら、状況は少し変わったようです。

  • PowerOff 機能org.freedesktop.login1は、"""new""" (咳! 咳!) SystemD機構の一部である新しいサービスを介して処理されるようです。
  • dbusPython パッケージは非推奨であるか、「レガシー」と見なされているようです。ただし、代わりに使用する新しいPyDbus ライブラリがあります。

したがって、特権のないスクリプトを使用してマシンの電源を切ることができます。

#! /usr/bin/python3
from pydbus import SystemBus
bus = SystemBus()

proxy = bus.get('org.freedesktop.login1', '/org/freedesktop/login1')
if proxy.CanPowerOff() == 'yes':
    proxy.PowerOff(False)  # False for 'NOT interactive'

アップデート 3.1:

思ったほど新しくはないようだXD

このまったく同じスレッドで@Roeftenによる回答がすでにあります。

ボーナス:

過熱を防ぐために、時間のかかる作業の後にコンピューターの電源を切りたいとのコメントを読みました... RTC を使用して、特定の時間に電源を入れることができることをご存知でしたか? (これこれを見てください)かなりクールですね。(これができるとわかったときはとても興奮しました...) :-D

于 2014-04-11T13:27:26.580 に答える
-1

私は Fedora を使用していますが、うまく動作します。私がする必要があるのは、ターミナルでこの行を書くことだけです:

$ sudo python  yourScript.py
于 2016-05-28T20:57:26.950 に答える