스크립트가 완료되기 전에 Ubuntu를 종료하지 않는 방식으로 설정할 수 있습니까?


15

스크립트를 사용하여 한 디스크에서 다른 디스크로 btrfs 파티션의 증분 백업을 수행합니다.

스크립트는 하루 중 임의의 시간에 cron.weekly에 의해 시작됩니다.

스크립트가 실행되는 동안 시스템을 종료하면 오래된 백업이 제거되고 새로 생성되지 않아 문제가 발생합니다.

스크립트가 끝날 때까지 시스템을 설정하는 방법이 있습니까?

systemd와 함께 Ubuntu 16.04를 사용하고 있습니다.


GUI 명령을 차단하는 방법이 있습니다. 나는 그것을위한 스크립팅 접근법을 가지고 있습니다. 그러나 sudo 사용자 가 수행하면 명령 줄을 차단할 수 없습니다 . GUI에 대한 과거 답변을 연결하겠습니다. 귀하의 필요에 맞게 맞춤 제작을 원하는지 알려주세요
Sergiy Kolodyazhnyy


1
@ByteCommander주의 : 사전 시스템화되어 있습니다.
Rinzwind

1
@Serg nice one :) 그러나 systemd-inhibit눈에 조금 쉽지 않습니까? >
:-D

1
스크립트가 잠기면 어떻게됩니까? 새 백업이 완료 될 때까지 이전 백업을 제거하지 않는 것이 좋지 않습니까? 시스템 종료를 막을 수는 있지만 시스템 고장이나 일반적인 전원 손실이 발생하는 상황을 막을 수는 없습니다. 두 경우 모두 이전 백업을 삭제하고 새 백업을 만들지 않은 채로 남아 있습니다.
Joe 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 시스템 하드웨어 덮개 스위치의 저수준 처리를 금지합니다.

또한 suspend, idle및 방지하고 싶을 것입니다 hibernate.


"패키지 관리자"를 사용하는 예 :

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

이와 유사하게 버전을 코딩하고이 스크립트의 끝에 "종료"를 추가 할 수 있습니다 (또는 다음 조치가 필요한 종료를 결정하는 방법 추가).


의견은 긴 토론을위한 것이 아닙니다. 여기에서 발생한 대화가 채팅 으로 이동 되었습니다 .
토마스 워드

2

BackInTime 에서는 모든 주요 DE에서 작동하기 위해 서로 다른 DBus 방법을 사용하고 있습니다. 단점은 no가 없기 root때문에 작동하지 않는다는 것입니다 .rootdbus.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.