как я могу обнаружить запущенную программу и прекратить выключение, прежде чем отключать систему? [dубликат]

Я использую скрипт для создания инкрементных резервных копий раздела btrfs с одного диска на другой.

Сценарий запускается cron.weekly в случайное время дня.

Если я закрою систему во время работы скрипта, у меня возникают проблемы с удалением старых резервных копий и новым не созданным.

Есть ли способ настроить систему на ожидание завершения скрипта? [ ! d3]

Я использую Ubuntu 16.04 с systemd.

15
задан 22 July 2016 в 12:48

4 ответа

В BackInTime я использую несколько разных методов DBus для работы со всеми основными DE. Единственный недостаток - это не будет работать для 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)
2
ответ дан 18 July 2018 в 09:28

Для 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 блокирует низкоуровневую обработку ключа приостановки аппаратного обеспечения. handle-hibernate-key блокирует низкоуровневую обработку системного спящего режима. handle-lid-switch подавляет низкоуровневую обработку переключателя аппаратной крышки systemd.

Вероятно, вы также хотите предотвратить suspend, idle и hibernate.

Есть 7 замков :

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

Аналогично этому вы можете запрограммировать свою версию и добавить «выключение», в конце этого скрипта (или добавить способ определения выключения должен быть следующим действием).

20
ответ дан 18 July 2018 в 09:28

В BackInTime я использую несколько разных методов DBus для работы со всеми основными DE. Единственный недостаток - это не будет работать для 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)
2
ответ дан 24 July 2018 в 19: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 блокирует низкоуровневую обработку ключа приостановки аппаратного обеспечения. handle-hibernate-key блокирует низкоуровневую обработку системного спящего режима. handle-lid-switch подавляет низкоуровневую обработку переключателя аппаратной крышки systemd.

Вероятно, вы также хотите предотвратить suspend, idle и hibernate.

Есть 7 замков :

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

Аналогично этому вы можете запрограммировать свою версию и добавить «выключение», в конце этого скрипта (или добавить способ определения выключения должен быть следующим действием).

20
ответ дан 24 July 2018 в 19:20

Другие вопросы по тегам:

Похожие вопросы: