您现在的位置是:首页 >技术教程 >shell脚本在linux重启之后继续运行网站首页技术教程
shell脚本在linux重启之后继续运行
文章目录
shell脚本在linux重启之后继续运行
问题
首先,我是需要写一个hadoop集群启动的脚本,脚本代码中有需要重启Linux
的操作,那么如何在重启Linux后,继续执行脚本中的代码呢?
我暂时查询到的方法如下:
一. nohup命令
nohup ./script.sh > log 2>&1 &
nohup命令用于忽略HUP信号(当用户退出登录时会发送这个信号),保证脚本不会因为用户退出而停止运行;
&符号用于将脚本放入后台运行;
>符号用于将标准输出重定向到log文件中;
2>&1则用于将标准错误输出也重定向到log文件中。
该命令只是将script.sh脚本文件放入后台运行,我们关闭命令行窗口时,不会影响该脚本的执行。
但是当脚本中执行到reboot重启命令时,linux重启,但重启之后的脚本代码依旧不会执行。
二. Systemd服务和开机自启动
要让shell脚本在Linux重启之后继续运行,可以使用Systemd服务来实现。具体步骤如下:
1.编写需要执行的shell脚本,并保存为script.sh文件。
2.创建一个Systemd服务配置文件,在终端中执行以下命令:
sudo vim /etc/systemd/system/script.service
在打开的文件中,添加以下内容:
[Unit]
Description=My Script Service
[Service]
ExecStart=/path/to/script.sh
Restart=always
User=myuser
[Install]
WantedBy=multi-user.target
其中,
Description用于描述服务的名称;
ExecStart指定需要执行的脚本文件路径;
Restart设置为always表示服务遇到错误时会自动重启;
User指定运行服务的用户。
3.保存并关闭文件,然后重新加载Systemd服务配置文件,执行以下命令:
sudo systemctl daemon-reload
4.启动服务,执行以下命令:
sudo systemctl enable script.service
sudo systemctl start script.service
5.验证服务是否正常运行,执行以下命令:
sudo systemctl status script.service
会显示如下:
● script.service - My Script Service
Loaded: loaded (/etc/systemd/system/script.service; enabled; vendor preset: disabled)
Active: inactive (dead)
取消服务的自启动
systemctl disable script.service
# 重启后生效
手动停止服务
systemctl stop script.service
centos7开机登陆页面死循环问题
为了测试这个开机自启动服务,我写了一个有reboot 命令的脚本代码
但是结果是遇到一个重启无限循环的问题
就是开启自启动服务后,会执行脚本代码,执行reboot重启命令,
然后就会陷入一个重启的无限循环中
解决
shell 脚本中有重启liunx的命令,如何防止陷入重启的死循环中
示例代码:
#!/bin/bash
# 检查系统是否已经在重启过程中
if [ -f /var/run/reboot-required ]; then
echo "System is already scheduled for reboot. Skipping..."
exit 0
fi
# 执行重启命令
sudo reboot
在shell脚本中,-f是一个条件测试运算符,
用于测试一个文件是否存在并且是一个普通文件。
具体来说,它会检查指定的路径是否存在并且是否为一个常规文件
(即不是目录或特殊设备文件等)。
除了-f运算符外,还有其他条件测试运算符可用于测试文件,
例如
-d(测试是否为目录)、
-e(测试是否存在任何类型的文件)、
-r(测试是否可读)等等。
/var/run/reboot-required文件是什么
该文件是由unattended-upgrades软件包创建的,并在更新安装后检查,以确定是否需要重启系统。如果应用了某些更新,例如内核更新或其它系统级别的更新,那么这些更新需要在系统重新启动后才能生效,因此该软件包会创建/var/run/reboot-required 文件来提醒管理员重新启动系统。
当管理员执行重启命令时,该文件将被删除,并且系统将重新启动。
因此,/var/run/reboot-required 文件的存在指示着系统已经需要进行重启操作,而不是重启操作已经完成。
简单解释
就是当安装了更新或者升级软件包等操作后,系统可能会要求重启以使更改生效。此时系统会在 /var/run/ 目录下创建一个名为 reboot-required 的文件,用来表示系统需要重启。因此,通过判断该文件是否存在,我们可以知道系统当前是否需要重启。
unattended-upgrades软件包是什么,centos7最小化安装时,会有这个软件包吗
unattended-upgrades是Debian/Ubuntu操作系统中的一个软件包,用于自动升级系统中的软件包和安全补丁。CentOS 7最小化安装通常不会包含此软件包,因为它是基于Red Hat Enterprise Linux (RHEL)而不是Debian/Ubuntu。
————————————————
注意:到此我们知道了,if [ -f /var/run/reboot-required ]; then
该脚本代码不满足我们的需求,并且在centos7中不起作用
创建标识文件,解决了重启后无限循环的问题
但是我们知道了一个方法
我们可以在执行reboot重启命令之前,先创建一个标识文件,
重启之后,判断这个标识文件是否存在,如果存在就不执行重启命令
测试代码如下:
#!/bin/bash
# 判断系统是否需要重启
if [ -e /shell_01/reboot-required ];
then
#sleep 60 # 等待60秒
echo "重启之后"
echo "bbbbbbbbbbbbbbbbbbbb"
sum=0
n=1
while ((n<=100))
do
((sum+=n))
((n++))
echo "重启之后"
echo $sum
done
else
mkdir -p /shell_01/reboot-required
reboot
fi
上述代码的意思就是运行脚本时,先判断/shell_01/reboot-required该标识文件是否存在,如果不存在,就先创建reboot-required并且执行重启命令,
如果将该脚本设置为开机自启动,那么重启后该脚本又会自动执行,先判断是否存在标识文件,存在,则执行下面的代码
这样就解决了linux开机界面不断重启的问题(也就是重启的无限循环问题),
设置开机自启动
vim /etc/systemd/system/script.service
内容如下:
[Unit]
Description=My Script Service
[Service]
Type=simple
ExecStart=/bin/bash -c '/shell_01/t.sh &> /shell_01/log &'
Restart=on-failure
User=root
[Install]
WantedBy=multi-user.target
-c后的 /shell_01/t.sh &> /shell_01/log & 命令
运行该脚本,将该脚本的输出重定向到/shell_01/log 文件中
开启自启动服务后,在控制台运行 /shell_01/t.sh &> /shell_01/log &
结果是会先重启,重启之后,查看/shell_01/log
结果符合预期设想
至此,shell脚本在linux重启之后继续运行的问题算是解决了
总结
shell脚本在linux重启之后继续运行问题
可以创建一个标识文件,判断该标识文件不存在则先创建标识文件再执行重启命令
若该文件存在则继续执行下面的代码
并且配合linux的自启动服务来完成
当然也可以不创建自启动服务,连续运行两次脚本也可以
也就是在未重启之前运行一次脚本,liunx会重启,
重启之后,在运行一次脚本,就会执行重启之后的命令