我如何在 Raspberry Pi (运行ning Raspbian) 关机或重启之前 运行 一个 Bash 脚本?

How do I run a Bash script before shutdown or reboot of a Raspberry Pi (running Raspbian)?

我想在关闭或重启我的 Pi 之前 运行 一个 Bash 脚本(运行使用最新的 Raspbian,Debian 的衍生版本)。

例如如果我在命令提示符中输入 sudo shutdown now 或 sudo reboot now,它应该 运行 我的 Bash 脚本,然后再继续 shutdown/reboot.

我创建了一个非常简单的脚本来进行测试,以确保在编写实际脚本之前我的方法可以正常工作:

#!/bin/bash
touch /home/pi/ShutdownFileTest.txt

然后我将文件(名为 CreateFile.sh)复制到 /etc/init。d/CreateFile 然后我在 /etc/rc0.d/ 和 /etc/rc6.d/:

中创建了符号链接
sudo ln -s /etc/init.d/CreateFile K99Dave

我不确定符号链接的正确命名应该是什么。有的网站说"Start the filename with a K",有的说"start with an S",有的说:"start with K99 so it runs at the right time"...

实际上我最终尝试了以下所有方法(当然不是一次全部,而是一次一个):

sudo ln -s /etc/init.d/CreateFile S00Dave
sudo ln -s /etc/init.d/CreateFile S99Dave
sudo ln -s /etc/init.d/CreateFile K00Dave
sudo ln -s /etc/init.d/CreateFile K01rpa
sudo ln -s /etc/init.d/CreateFile K99Dave

创建每个符号链接后,我总是 运行:

sudo chmod a+x /etc/init.d/CreateFile && sudo chmod a+x /etc/rc6.d/<name of symlink>

然后我每次都重启。

每次都没有创建位于/home/pi/ShutdownFileTest.txt 的文件;脚本未执行。

我在较旧的post上找到了this comment,提示以上是过时的方法:

The modern way to do this is via systemd. See "man systemd-shutdown" for details. Basically, put an executable shell script in /lib/systemd/system-shutdown/. It gets passed an argument like "halt" or "reboot" that allows you to distinguish the various cases if you need to.

我将我的脚本复制到 /lib/systemd/system-shutdown/,chmod +x'它,然后重新启动,但仍然没有成功。

我注意到上面的评论说脚本是作为参数传递的 "halt" 或 "reboot"。由于在这两种情况下它应该 运行 相同,所以我认为它不需要实际处理该参数。我也不知道如何处理这个论点,所以我不确定我是否需要做点什么来使它起作用...

有人能告诉我哪里错了吗?

提前致谢, 戴夫

事实证明,在执行这些脚本之前,部分关闭命令已经执行(并卸载了文件系统)。

因此,在脚本开始时挂载文件系统并在结束时卸载是必要的。

只需添加:

mount -oremount,rw /

...在脚本开头(#!/bin/bash 下方)

...然后有脚本的代码...

然后完成脚本:

mount -oremount,ro /

所以,OP脚本应该变成:

#!/bin/bash
mount -oremount,rw /
touch /home/pi/ShutdownFileTest.txt
mount -oremount,ro /

...然后在 shutdown/reboot.

之前创建文件 /home/pi/ShutdownFileTest.txt

也就是说,使用此方法可能不是最佳做法。相反,最好创建一个服务,该服务在计算机开机时 运行s 正常 运行ning,但在服务终止时 运行s 所需的脚本(发生在 shutdown/reboot).

这里有详细解释here,但本质上:

1:创建一个文件(暂且称之为example.service)。

2:在example.service中添加以下内容:

[Unit]
Description=This service calls shutdownScript.sh upon shutdown or reboot.

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=/home/pi/shutdownScript.sh

[Install]
WantedBy=multi-user.target

3:通过 运行ning sudo mv /home/pi/example.service /etc/systemd/system/example.service

将其移动到 systemd 的正确目录中

4:确保关机时启动的脚本具有适当的权限:chmod u+x /home/pi/shutdownScript.sh

5:启动服务:sudo systemctl start example --now

6:使服务在开机时自动启动:sudo systemctl enable example

7:停止服务:sudo systemctl stop example

最后一条命令将模仿系统关闭时正常发生的情况,即它将 运行 /home/pi/shutdownScript.sh(实际上并没有关闭系统)。

然后你可以重新启动两次,它应该从第二次重新启动开始工作。

编辑:不,不,不是。它在我第一次测试时工作,但之后就停止工作了。不知道为什么。如果我弄清楚如何让它工作,我将编辑此答案并删除此消息(或者如果其他人知道,请随时为我编辑答案)。

由于我没有足够的尊严来 post 发表评论,这是一个新的答案,对此我深表歉意。

我在 ZPMMaker 的答案中添加了一个步骤,它似乎至少对我有用。

sudo chmod u+x /etc/systemd/system/example.service