Сценарии выхода из системы: не завершены при завершении работы, перезагрузите компьютер

Я пытаюсь сделать некоторые вещи при выходе из системы, и задача может занять до 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-orig
b. 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 линия.

Как и до выключения, пользователь все равно выходит из системы, это должно охватывать обе базы.

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