您现在的位置是:首页 >技术教程 >shell脚本在linux重启之后继续运行网站首页技术教程

shell脚本在linux重启之后继续运行

王轩12 2023-07-08 20:00:03
简介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重启命令,
然后就会陷入一个重启的无限循环中

解决

VMware下centos7开机登陆页面死循环问题详细解决

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会重启,
重启之后,在运行一次脚本,就会执行重启之后的命令

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。