スクリプトが完了する前にシャットダウンしないようにUbuntuを設定することは可能ですか?


15

スクリプトを使用して、1つのディスクから別のディスクへのbtrfsパーティションの増分バックアップを実行します。

スクリプトは、cron.weeklyによって1日のランダムな時間に開始されます。

スクリプトの実行中にシステムをシャットダウンすると、古いバックアップが削除され、新しいバックアップが作成されないという問題が発生します。

スクリプトが終了するまで待つようにシステムをセットアップする方法はありますか?

systemdでUbuntu 16.04を使用しています。


GUIコマンドをブロックする方法があります。そのためのスクリプト作成のアプローチがあります。ただし、sudo ユーザーが実行した場合、コマンドラインはブロックできません。GUIの過去の回答をリンクします。あなたはそれがあなたのニーズに合わせてカスタマイズしたい場合は、私に教えてください
Sergiy Kolodyazhnyy


1
@ByteCommander注意:これらは事前にシステム化されています。
リンツウィンド

1
@Serg nice one :)しかしsystemd-inhibit、目には少し楽ではないですか?>:-D
Rinzwind

1
スクリプトがロックするとどうなりますか?とにかく新しいバックアップが終了するまで古いバックアップを削除しない方が良いと思いませんか?シャットダウンを防ぐことはできるかもしれませんが、システム障害や一般的な電力損失が発生する状況を防ぐことはできません。どちらの場合でも、古いバックアップは削除されたままで、新しいバックアップは作成されません。
ジョーW

回答:


20

systemdを使用するUbuntu 16.04以降(デフォルト)。

systemd-inhibit --why="Wait for this script to finish" bash script.sh

===

テスト:

$ systemctl poweroff
Operation inhibited by "bash script.sh" (PID 23912 "systemd-inhibit", user rinzwind),
reason is "Wait for this script to finish".
Please retry operation after closing inhibitors and logging out other users.

===

7つのロックがあります

  • sleep (非特権)ユーザーが要求するシステムのサスペンドおよび休止状態を禁止します
  • shutdown (非特権)ユーザーが要求する高レベルのシステム電源オフと再起動を禁止します
  • idle システムがアイドルモードになるのを抑制し、構成に応じてシステムの自動サスペンドまたはシャットダウンを行う可能性があります。
  • handle-power-key システム電源ハードウェアキーの低レベル(つまり、ログイン内部)処理を禁止し、代わりに(おそらく特権のない)外部コードがイベントを処理できるようにします。
  • handle-suspend-key システムハードウェアの一時停止キーの低レベルの処理を禁止します。
  • handle-hibernate-key システムハードウェア休止状態キーの低レベルの処理を禁止します。
  • handle-lid-switch systemdハードウェアリッドスイッチの低レベルの処理を禁止します。

またsuspend、おそらく防止したい、idlehibernate


「パッケージマネージャー」を使用した例

fd = Inhibit("shutdown:idle", "Package Manager", "Upgrade in progress...", "block");
/* ...
      do your work
                 ... */
close(fd);

これと同様に、バージョンをコーディングし、このスクリプトの最後に「シャットダウン」を追加できます(または、シャットダウンが次のアクションである必要があるかどうかを判断する方法を追加します)。


コメントは詳細なディスカッション用ではありません。ここで行われていた会話はチャットに移動しました
トーマスウォード

2

BackInTime私はすべての主要なDEの上の仕事へのカップル異なるDBusの方法を使用しています。欠点は、がないため、rootこれrootが機能しないことdbus.SessionBusです。

#!/usr/bin/env python3
import sys
import dbus
from time import sleep

INHIBIT_LOGGING_OUT = 1
INHIBIT_USER_SWITCHING = 2
INHIBIT_SUSPENDING = 4
INHIBIT_IDLE = 8

INHIBIT_DBUS = (
               {'service':      'org.gnome.SessionManager',
                'objectPath':   '/org/gnome/SessionManager',
                'methodSet':    'Inhibit',
                'methodUnSet':  'Uninhibit',
                'interface':    'org.gnome.SessionManager',
                'arguments':    (0, 1, 2, 3)
               },
               {'service':      'org.mate.SessionManager',
                'objectPath':   '/org/mate/SessionManager',
                'methodSet':    'Inhibit',
                'methodUnSet':  'Uninhibit',
                'interface':    'org.mate.SessionManager',
                'arguments':    (0, 1, 2, 3)
               },
               {'service':      'org.freedesktop.PowerManagement',
                'objectPath':   '/org/freedesktop/PowerManagement/Inhibit',
                'methodSet':    'Inhibit',
                'methodUnSet':  'UnInhibit',
                'interface':    'org.freedesktop.PowerManagement.Inhibit',
                'arguments':    (0, 2)
               })

def inhibitSuspend(app_id = sys.argv[0],
                    toplevel_xid = None,
                    reason = 'take snapshot',
                    flags = INHIBIT_SUSPENDING | INHIBIT_IDLE):
    """
    Prevent machine to go to suspend or hibernate.
    Returns the inhibit cookie which is used to end the inhibitor.
    """
    if not app_id:
        app_id = 'backintime'
    if not toplevel_xid:
        toplevel_xid = 0

    for dbus_props in INHIBIT_DBUS:
        try:
            bus = dbus.SessionBus()
            interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
            proxy = interface.get_dbus_method(dbus_props['methodSet'], dbus_props['interface'])
            cookie = proxy(*[(app_id, dbus.UInt32(toplevel_xid), reason, dbus.UInt32(flags))[i] for i in dbus_props['arguments']])
            print('Inhibit Suspend started. Reason: %s' % reason)
            return (cookie, bus, dbus_props)
        except dbus.exceptions.DBusException:
            pass
    print('Inhibit Suspend failed.')

def unInhibitSuspend(cookie, bus, dbus_props):
    """
    Release inhibit.
    """
    assert isinstance(cookie, int), 'cookie is not int type: %s' % cookie
    assert isinstance(bus, dbus.bus.BusConnection), 'bus is not dbus.bus.BusConnection type: %s' % bus
    assert isinstance(dbus_props, dict), 'dbus_props is not dict type: %s' % dbus_props
    try:
        interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
        proxy = interface.get_dbus_method(dbus_props['methodUnSet'], dbus_props['interface'])
        proxy(cookie)
        print('Release inhibit Suspend')
        return None
    except dbus.exceptions.DBusException:
        print('Release inhibit Suspend failed.')
        return (cookie, bus, dbus_props)

if __name__ == '__main__':
    cookie, bus, dbus_props = inhibitSuspend()
    print('do something here')
    sleep(10)
    unInhibitSuspend(cookie, bus, dbus_props)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.