Ubuntu'yu komut dosyası bitmeden kapanmayacak şekilde ayarlamak mümkün müdür?


15

Bir btrfs bölümünün bir diskten diğerine artımlı yedeklemeler yapmak için bir komut dosyası kullanıyorum.

Senaryo cron.weekly tarafından günün rastgele zamanında başlatılır.

Komut dosyası çalışırken sistemi kapatırsam, eski yedeklemeler kaldırılır ve yeni oluşturulmaz.

Komut dosyası bitene kadar sistemi kurmanın bir yolu var mı?

Systemd ile Ubuntu 16.04 kullanıyorum.


GUI komutlarını engellemenin bir yolu vardır. Bunun için senaryo yaklaşımım var. Ancak komut satırı sudo kullanıcı tarafından yapılırsa engellenemez . GUI için geçmiş bir cevabı bağlayacağım. İhtiyaçlarınıza uyacak şekilde özelleştirilmesini istiyorsanız bana bildirin
Sergiy Kolodyazhnyy


1
@ByteCommander dikkatli: bunlar ön-sistemd.
Rinzwind

1
@ Güzel biri :) :) systemd-inhibitGözlerde biraz daha kolay değil mi? D
Rinzwind

1
Betik kilitlenirse ne olur? Yeniler zaten bitene kadar eski yedeklemelerinizi kaldırmamak daha iyi olmaz mıydı? Kapatmayı engelleyebilmenize rağmen, sistem arızası veya genel güç kaybının olduğu bir durumu engelleyemezsiniz. Her iki durumda da, eski yedeklemeniz silinmiş ve yeni yedeklenmemiş olarak kalırsınız.
Joe W

Yanıtlar:


20

Systemd kullanan Ubuntu 16.04+ için (varsayılan).

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

===

Ölçek:

$ 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 kilit vardır :

  • sleep (ayrıcalıksız) kullanıcılar tarafından istenen sistem askıya alınmasını ve hazırda bekletme modunu engeller
  • shutdown (ayrıcalıklı olmayan) kullanıcılar tarafından istenen yüksek düzeyde sistem kapanmasını ve yeniden başlatmayı engeller
  • idle sistemin bekleme moduna geçmesini engeller, bu da muhtemelen yapılandırmaya bağlı olarak otomatik sistem askıya alma veya kapatma ile sonuçlanır.
  • handle-power-key sistem güç donanım anahtarının düşük düzeyde (yani logind-internal) işlenmesini engeller, bunun yerine (muhtemelen ayrıcalıklı olmayan) harici kodun olayı işlemesine izin verir.
  • handle-suspend-key sistem donanım askıya alma tuşunun düşük düzeyde kullanımını engeller.
  • handle-hibernate-key sistem donanım hazırda bekletme anahtarının düşük düzeyli kullanımını engeller.
  • handle-lid-switch sistemd donanım kapağı anahtarının düşük seviyeli kullanımını engeller.

Muhtemelen de önlemek istiyoruz suspend, idleve hibernate.


"Paket yöneticisi" kullanımına örnek :

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

Buna benzer şekilde, sürümünüzü kodlayabilir ve bu komut dosyasının sonuna bir "kapanma" ekleyebilirsiniz (veya bir sonraki eylemin kapatılması gerektiğini belirlemek için bir yol ekleyebilirsiniz).


Yorumlar uzun tartışmalar için değildir; burada gerçekleşen konuşma sohbete taşındı .
Thomas Ward

2

In BackInTime Ben tüm büyük DE'lere üzerinde çalışmaya birkaç farklı DBus yöntemleri kullanıyorum. Sadece olumsuz, bu işe yaramaz rootçünkü roothayır vardır 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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.