Як запустити скрипт перед завершенням роботи з системою?


17

Примітка: стисло сформульоване запитання можна знайти внизу.

У мене є сценарій, який робить резервну копію моїх файлів на зовнішньому накопичувачі USB. Виконання цього може зайняти деякий час, залежно від кількості нових даних, які я створив. Я хочу запустити його автоматично при кожному відключенні системи.

Я використовую fedora 23 з останніми оновленнями (systemd).

Я намагався досягти цього кількома способами, але не зміг змусити його працювати.

Тривалий процес з StopExec

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

Я активував його systemctl enable autobackup.serviceі почав з нього systemctl start autobackup.service.

Частина мого журналу завантаження ( journalctl -b-1):

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

Зауважте, що я нічого не скорочував між ними, він дійсно відключений / mnt / BACKUP безпосередньо перед запуском сценарію, смішний збіг.

Перед shutdown.target

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

Вихідний результат в основному однаковий.

Проблема

Я думаю, що проблема полягає в тому, що systemd запускає мій скрипт паралельно з усіма іншими скриптами відключення в обох випадках, які відключають BACKUP та деактивують інфраструктуру труби (інша помилка, яку я іноді отримував, коли відключення не було досить швидким).

Питання

Як я можу навчити systemd спершу запускати сценарій після вимкнення, дочекатися його завершення, а потім запустити решта скриптів / цілей / одиниць відключення / що завгодно?

Відповіді:


12

Не потрібно створювати або редагувати сервісні файли. Просто киньте свій сценарій

/usr/lib/systemd/system-shutdown/

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

Безпосередньо перед виконанням фактичної зупинки системи / poweroff / reboot / kexec systemd-shutdown запустить усі виконувані файли в / usr / lib / systemd / system-shutdown / і передасть їм один аргумент: або "halt", "poweroff", "reboot "або" kexec ", залежно від обраної дії. Всі виконувані файли в цьому каталозі виконуються паралельно, і виконання дії не продовжується до того, як всі виконувані файли закінчені.

Я використовую його, щоб просто подати звуковий сигнал для динаміка ПК.


2
Вам довелося скласти цей каталог? У мене немає ні на Ubuntu 16.04, ні на Raspbian (jessie) - і те, і інше базуються на системах.
— WoJ

2
Системи Debian використовують інший шлях /lib/systemd/system-shutdown/. А крім того, майте на увазі, що ці сценарії виконуються дуже пізно після вимкнення, після того як файлові системи вже змонтовані лише для читання. Таким чином, будь-який доступ до запису до файлової системи не вдасться, якщо їх не перерахувати як read-write ( mount -oremount,rw /). Див. Як виконувати сценарії в / usr / lib / systemd / system-shutdown / при перезавантаженні чи відключенні?
— Френк Брейтлінг

9
ОП попросив виконати сценарій "до всього іншого" при відключенні. Сценарії відключення системи виконуються після всього іншого, безпосередньо перед вбивством ядра.
— Грег Олександр

11

Зрозумів!

Візьміть тривалий процес рішення із StopExec та змініть його так:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Зверніть увагу на рядок:

RequiresMountsFor=/mnt/BACKUP /home

Це працює, як очікувалося таким чином.


2
Вам не потрібно робити це systemctl edit. systemctl enable autobackupмає такий же ефект і є більш ідіоматичним, і він повинен працювати, оскільки у вас вже є [Install]розділ у вашому підрозділі. Однак вам доведеться виправити цю помилку в назві цілі. ;)
— Стефан Маєвський

OMG Я так довго шукав рішення, як викликати мій резервний скрипт ДО ПЕРЕД будь-яких дисків не відключено. Дякую!
— deanresin

2
Це не працює для мене. У мене немає жодних кріплень, я просто хочу переконатися, що мій сценарій працює до того, як інші блоки вимкнуться.
— 2rs2ts
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.