我尝试在注销时做一些事情,该任务可能需要最多 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 上。
答案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 脚本重新启动时进行处理。根据任务的不同,这可能根本不是问题。