Сценарии выхода из системы: не завершены при завершении работы, перезагрузите компьютер
Я пытаюсь сделать некоторые вещи при выходе из системы, и задача может занять до 5 минут.
Если пользователь выбирает Power off или же Reboot непосредственно, сценарий убит до завершения. Если пользователь просто выбирает Log outСценарий выполнен без проблем.
Я пытался использовать pam_exec а также lightdm имущество session-cleanup-script указать на мой сценарий, но он одинаков в обоих случаях.
Сценарий, использованный для тестирования:
#!/bin/bash
touch /tmpfile
for p in $(seq 0 300) ; do
sleep 1
echo $p >> /tmpfile
done
При выходе все 300 чисел записываются в файл. При выключении или перезагрузке непосредственно из пользовательского сеанса записываются только 2 или 3 числа, поэтому сценарий уничтожается.
Как обрабатывается выключение с помощью lightdm? Как я могу гарантировать, что мой сценарий не будет убит?
Если вы предлагаете альтернативный подход, пожалуйста, позаботьтесь о том, чтобы мне нужно было знать, какой пользователь выходит из системы, и иметь возможность запускать сценарий от имени этого пользователя. Мне также нужно уведомить пользователя о том, что происходит, поэтому лучше остаться на X, если это возможно.
3 ответа
Чтобы справиться с этим, я объединил три механизма:
- Сценарий выхода Lightdm, который получает информацию о пользователе и записывает ее во временный файл, чтобы мы могли знать, кто выключает компьютер. Это также делает тяжелую задачу в случае, если мы не выключаемся или не перезагружаемся.
- Традиционные сценарии initrd для выполнения тяжелых задач при завершении работы или перезагрузке.
- Плимутские сообщения о состоянии, чтобы дать отзыв о тяжелых задачах при выключении или перезагрузке.
Итак, у меня есть сценарий тяжелой задачи на /usr/local/bin/heavy.sh:
#!/bin/bash
touch /tmpfile
for p in $(seq 0 300) ; do
sleep 1
echo $p >> /tmpfile
if [ ! -z $DISPLAY ] ; then
notify-send "Written $p"
else
plymouth message --text="Written $p" &>/dev/null
fi
done
Эта тяжелая задача пытается вывести информацию в X. Если это не удается, пытается сделать это в Плимут.
Затем я добавил эту строку в конфигурацию Lightdm на /etc/lightdm/lightdm.conf:
session-cleanup-script=/usr/local/sbin/logout-tasks.sh
Указанный скрипт записывает пользователя при выходе из системы и пытается выполнить тяжелую задачу:
#!/bin/bash
echo $USER > /run/last-logout-user
/usr/local/bin/heavy.sh
Скрипт initrd, расположенный на /etc/init.d/logout-heavy-task-at-shutdown:
#!/bin/bash
USER_RUN=$(cat /run/last-logout-user)
sudo -u $USER_RUN /usr/local/bin/heavy.sh
Это запускает задачу как последний зарегистрированный пользователь при завершении работы и перезапуске, учитывая, что мы добавили соответствующие ссылки:
update-rc.d -n logout-heavy-task-at-shutdown start 05 0
update-rc.d -n logout-heavy-task-at-shutdown start 05 6
И это все. Тяжелая задача, возможно, придется обрабатывать, когда она уничтожается X, а затем снова запускается сценарием initrd. В зависимости от задачи это не может быть проблемой.
В Ubuntu сценарии для разных уровней выполнения выполняются в соответствии с их присутствием в /etc/rc[0-6].d каталоги. Runlevel 0 соответствует выключению, а 6 перезагрузке.
Обычно скрипт хранится в /etc/init.d, а затем символические ссылки помещаются в каталоги, соответствующие требуемым уровням выполнения.
Так что в вашем случае напишите свой скрипт, сохраните его в /etc/init.d/затем создайте символическую ссылку в каждом из /etc/rc0.d а также /etc/rc6.d (если вы хотите оба), указывая на ваш сценарий.
Создайте символическую ссылку, например: /etc/rc0.d/K01myscipt -> /etc/init.d/myscript
Сценарии в каждом каталоге уровня выполнения будут выполняться в ASCIIbetical порядке, поэтому, если для вас важен порядок в уровне выполнения, выберите имя вашей символической ссылки соответственно.
Надеюсь, что это решает. Не забудьте сделать его исполняемым (sudo chmod +x myscript). Кроме того, я не уверен, но, возможно, вам придется отменить выключение в начале сценария - shutdown -c now и выдать его снова в конце - shutdown -h now,
Теперь узнать, кто выпустил shutdown команда:
1) Либо, вы можете сделать это с помощью скрипта-обёртки следующим образом:
a. mv /sbin/shutdown /sbin/shutdown-origb. vim /sbin/shutdown
#!/bin/sh
echo "$USER has initiated the shutdown process" >> /var/log/shutdown.owner
/sbin/shutdown-orig "$@"c. chmod 755 /sbin/shutdown
2) Или обычный пользователь имеет доступ только к shutdown команда через sudo а также sudo команды (как правило) вошли в /var/log/, Итак, вы можете проверить это. Надеюсь, поможет. Для получения дополнительной информации, пожалуйста, обратитесь к моей теме здесь. Не забудьте зайти и сказать спасибо им.
РЕДАКТИРОВАТЬ: В заключение, если ничего не работает, попробуйте использовать sudo и заблокировать доступ к выключению / перезагрузке, и только тогда вы сможете проверить журналы и узнать, кто инициировал процесс выключения. Подробности в содержании ниже. Благодарю. Wonderful Question, Learnt a Lot.
LightDM
Создать скрипт в /etc/rc0.d,
sudo vim /etc/rc0.d/myScript
sudo chmod +x /etc/rc0.d/myScript
GDM
Добавьте свою команду в файл /etc/gdm/PostSession/Default перед exit 0 линия.
Как и до выключения, пользователь все равно выходит из системы, это должно охватывать обе базы.