我如何在 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
我想在关闭或重启我的 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
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