注销脚本:关机、重启时未完成

注销脚本:关机、重启时未完成

我尝试在注销时做一些事情,该任务可能需要最多 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

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

lightdm 如何处理关闭?如何确保我的脚本不会被终止?

如果您建议采用替代方法,请注意我需要知道哪个用户正在注销,并且能够以该用户的身份运行脚本。我还需要通知用户正在发生的事情,因此如果可能的话最好留在 X 上。

答案1

在 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

每个运行级别目录中的脚本将按照 ASCII 顺序执行,因此如果运行级别内的顺序对您很重要,请相应地选择符号链接的名称。

希望这能解决问题。别忘了让它可执行(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.

答案2

光子发射

在 中创建一个脚本/etc/rc0.d

sudo vim /etc/rc0.d/myScript
sudo chmod +x /etc/rc0.d/myScript

妊娠期糖尿病

将您的命令添加到文件中/etc/gdm/PostSession/Default该行之前exit 0

由于在关机之前用户无论如何都会被注销,这应该涵盖两个基础。

答案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。如果失败,则尝试将其输出到 Plymouth。

然后,我在 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 脚本重新启动时进行处理。根据任务的不同,这可能根本不是问题。

相关内容