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


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.