注销脚本:关闭时未完成,重新启动

Jor*_*Lis 5 shutdown scripts logout lightdm 12.04

我正在尝试在注销时做一些事情,该任务最多可能需要 5 分钟才能完成。

如果用户选择Power offReboot直接,则脚本在完成之前被杀死。如果用户只是选择Log out,则脚本将毫无问题地执行。

我试过使用pam_execlightdm属性session-cleanup-script指向我的脚本,但在这两种情况下都是一样的。

用于进行测试的脚本是这样的:

#!/bin/bash
touch /tmpfile
for p in $(seq 0 300) ; do
    sleep 1
    echo $p >> /tmpfile
done
Run Code Online (Sandbox Code Playgroud)

注销时,所有 300 个数字都会写入文件。在用户会话中直接关闭或重新启动时,只写入了 2 或 3 个数字,因此脚本被终止。

lightdm 是如何处理关机的?如何确保我的脚本不会被杀死?

如果您提出替代方法,请注意我需要知道正在注销的用户并能够以该用户身份运行脚本。我还需要通知用户发生了什么,所以如果可能的话最好留在 X 上。

Jor*_*Lis 0

为了解决这个问题,我结合了三种机制:

  • 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
Run Code Online (Sandbox Code Playgroud)

这项繁重的任务尝试向 X 输出信息。如果失败,则尝试向 Plymouth 输出信息。

然后,我将此行添加到 Lightdm 配置中/etc/lightdm/lightdm.conf

session-cleanup-script=/usr/local/sbin/logout-tasks.sh
Run Code Online (Sandbox Code Playgroud)

引用的脚本在注销时记录用户并尝试执行繁重的任务:

#!/bin/bash
echo $USER > /run/last-logout-user
/usr/local/bin/heavy.sh
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

考虑到我们添加了相应的链接,在关闭和重新启动时,将作为最后注销的用户启动任务:

 update-rc.d -n logout-heavy-task-at-shutdown start 05 0
 update-rc.d -n logout-heavy-task-at-shutdown start 05 6
Run Code Online (Sandbox Code Playgroud)

就是这样。当繁重的任务被 X 杀死然后由 initrd 脚本再次启动时,可能需要处理它。根据任务的不同,这可能根本不是问题。