เป็นไปได้ไหมที่จะตั้ง Ubuntu ในลักษณะที่ไม่ได้ปิดระบบก่อนที่สคริปต์จะเสร็จสิ้น


15

ฉันใช้สคริปต์เพื่อสำรองข้อมูลส่วนเพิ่มของพาร์ทิชัน btrfs จากดิสก์หนึ่งไปยังอีก

สคริปต์เริ่มต้นโดย cron.weekly ในเวลาสุ่มของวัน

หากฉันปิดระบบในขณะที่สคริปต์กำลังทำงานอยู่ฉันกำลังมีปัญหากับการสำรองข้อมูลเก่าที่ถูกลบออกและไม่ได้สร้างใหม่

มีวิธีการตั้งค่าระบบให้รอจนกว่าสคริปต์จะเสร็จสิ้นหรือไม่

ฉันใช้ Ubuntu 16.04 กับ systemd


มีวิธีการบล็อกคำสั่ง GUI ฉันมีวิธีการเขียนสคริปต์สำหรับสิ่งนั้น แต่บรรทัดคำสั่งเป็นไปไม่ได้ที่จะปิดกั้นถ้าทำโดยsudo ผู้ใช้ ฉันจะลิงค์คำตอบที่ผ่านมาสำหรับ GUI แจ้งให้เราทราบหากคุณต้องการให้มันเหมาะกับความต้องการของคุณ
Sergiy Kolodyazhnyy

ที่เกี่ยวข้อง: เรียกใช้สคริปต์เมื่อออกจากระบบ / รีบูต / ปิดในอูบุนตูและเรียกใช้สคริปต์ก่อนที่จะปิดลง
ผู้บัญชาการไบต์

1
@ ByteCommander ระวัง: นั่นคือ pre-systemd
Rinzwind

1
@Serg nice หนึ่ง :) แต่ไม่ได้systemd-inhibitเป็นเรื่องง่ายขึ้นในสายตา? >: - D
Rinzwind

1
จะเกิดอะไรขึ้นถ้าสคริปต์ล็อคขึ้น จะเป็นการดีกว่าหรือไม่ที่จะไม่ลบการสำรองข้อมูลเก่าของคุณจนกว่าการสำรองข้อมูลใหม่จะเสร็จสิ้น ในขณะที่คุณสามารถป้องกันการปิดเครื่องคุณไม่สามารถป้องกันสถานการณ์ที่มีความล้มเหลวของระบบหรือการสูญเสียพลังงานทั่วไป ไม่ว่าในกรณีใดคุณจะยังคงมีข้อมูลสำรองเก่าถูกลบทิ้งและไม่ได้สร้างข้อมูลสำรองใหม่
Joe W

คำตอบ:


20

สำหรับ Ubuntu 16.04+ โดยใช้ systemd (ค่าเริ่มต้น)

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 ยับยั้งการจัดการระดับต่ำของคีย์ suspend ของฮาร์ดแวร์ระบบ
  • handle-hibernate-key ยับยั้งการจัดการระดับต่ำของคีย์ไฮเบอร์เนตฮาร์ดแวร์ระบบ
  • handle-lid-switch ยับยั้งการจัดการระดับต่ำของสวิตช์ฮาร์ดแวร์ฝา systemd

คุณอาจยังต้องการที่จะป้องกันไม่ให้suspend, และidlehibernate


ตัวอย่างการใช้ "package manager" :

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

คุณสามารถเขียนโค้ดเวอร์ชันของคุณและเพิ่ม "การปิดระบบ" ที่ส่วนท้ายของสคริปต์นี้ (หรือเพิ่มวิธีในการพิจารณาว่าการปิดระบบนั้นจะต้องเป็นการกระทำถัดไป)


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนาที่กำลังเกิดขึ้นที่นี่ได้รับการย้ายไปแชท
โธมัสวอร์ด

2

ในBackInTimeฉันใช้สองวิธี DBus ที่แตกต่างกันในการทำงานกับ DE ที่สำคัญทั้งหมด เพียง แต่ข้อเสียคือนี้จะไม่ทำงาน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.