使用Systemd CentOS/RHEL 7/8启动N分钟后如何运行脚本

时间:2020-02-23 14:40:22  来源:igfitidea点击:

在本文中,我将共享systemd单元文件和示例,以在使用systemd启动N分钟后运行脚本(不适用于cron作业)。
理想情况下,也可以使用cron作业完成此类任务,但是由于我们已经进行了systemd操作,那么为什么还要依赖cron作业呢?

使用OnBootSec =或者OnStartupSec =我们可以在启动N分钟后根据N上的值轻松运行脚本。
让我们使用一些示例来验证这一点:

systemd.timer概述

  • 名称以.timer结尾的单元配置文件对有关受systemd控制和监督的计时器的信息进行编码,以用于基于计时器的激活。

  • 通用配置项目在通用[Unit]和[Install]部分中进行配置。
    特定于计时器的配置选项在[Timer]部分中配置。

  • 对于每个计时器文件,必须存在一个匹配的单位文件,该文件描述了计时器经过时要激活的单位。

  • 默认情况下,激活与计时器同名的服务(后缀除外)。
    示例:计时器文件foo.timer激活匹配的服务foo.service。
    可以通过" Unit ="控制要激活的单位

  • 请注意,如果要激活的单元在计时器经过时已经处于激活状态,则它不会重新启动,而只是保持运行状态。
    在这种情况下,没有产生新服务实例的概念。

  • 因此,设置了" RemainAfterExit ="的服务(即使在服务的主要进程退出后仍会持续存在)通常不适合通过重复计时器激活,因为它们只会被激活一次,然后永远存在。

  • 计时器单元会自动获得对它们应激活的服务的Before =依赖关系。

  • 计时器单元将自动具有对sysinit.target的类型为Requires =和After =的依赖关系,以及对timers.target的类型为Before =的依赖关系,以及对的Conflicts =和Before =的依赖性shutdown.target以确保它们在系统关闭之前已干净地停止。

要列出环境中所有可用的计时器,请使用

# systemctl list-timers

创建示例脚本

要在使用systemd引导N分钟后运行脚本,我们将创建一个虚拟脚本,该脚本将在引导5分钟后将一些内容放入空文件中。

[root@centos-8 ~]# cat /tmp/delay_script.sh
#!/bin/bash
echo "Hello hynman, I am running late" >> /tmp/file

提供脚本的可执行权限

[root@centos-8 ~]# chmod u+x /tmp/delay_script.sh

在启动N分钟后,采样系统化的单元服务文件以运行脚本

其中我们必须创建一个systemd单元服务文件和一个匹配的systemd单元计时器文件,以在启动N分钟后运行脚本。
我们可以在Linux引导后使用OnBootSec =或者OnStartupSec =来延迟运行脚本

.1:OnBootSec与OnStartupSec

  • OnBootSec =定义相对于机器启动时间的计时器。
    在容器中,对于系统管理器实例,此映射到OnStartupSec =,使两者等效。

  • OnStartupSec =定义相对于服务管理器首次启动的计时器。
    对于系统计时器单元,这与" OnBootSec ="非常相似,因为系统服务管理器通常在启动时就非常早地启动。
    当以每用户服务管理器中运行的单元进行配置时,它主要有用,因为用户服务管理器通常仅在首次登录时启动,而不是在引导过程中启动。

[root@centos-8 ~]# cat /etc/systemd/system/run-script-with-delay.service
[Unit]
Description=Run script at startup
[Service]
Type=oneshot
ExecStart=/tmp/delay_script.sh
TimeoutStartSec=0

说明:

如果我们在.service单位文件中放置[Timer]部分,则将导致" systemctl失败,出现未知的Timer部分"错误。
[Timer]必须仅在.timer单位文件中使用

在启动N分钟后,示例系统单元计时器文件即可运行脚本

" timer"是一个单位配置文件,其名称以.timer结尾,用于编码有关由systemd控制和监督的计时器的信息,用于基于计时器的激活。

[root@centos-8 ~]# cat /etc/systemd/system/run-script-with-delay.timer
[Unit]
Description="Run script after 5 minutes of boot"
[Timer]
OnBootSec=5min
[Install]
WantedBy=default.target

提示:

通过使用Timer下的Unit =,可以提供在该计时器经过时要激活的单位。
其中由于我们的systemd服务和计时器文件具有相同的名称,即run-script-with-delay,因此我们在计时器单位文件中未定义任何Unit =
如果单位服务和计时器文件名不同,请在[计时器]下的.timer文件中为映射的服务文件名提供Unit =

其中用于OnBootSec或者OnStartupSec

  • 指令的参数是以秒为单位配置的时间跨度。
    示例:OnBootSec = 50表示启动后50秒。

  • 该参数还可以包括时间单位。
    示例:OnBootSec = 5h 30min表示在启动后5小时30分钟。

  • 有关OnBootSec =或者OnStartupSec =支持的时间跨度语法的详细信息,请参见systemd.timer的手册页。

刷新systemd配置文件

[root@centos-8 ~]# systemctl daemon-reload

禁用systemd单元服务文件,因为它不应自动启动,这就是本文的主旨。
我们希望该服务在启动N分钟后根据计时器值运行脚本。

[root@centos-8 ~]# systemctl disable run-script-with-delay.service
Removed /etc/systemd/system/default.target.wants/run-script-with-delay.service.

接下来,启用systemd单元计时器文件,以便它将在启动后运行,然后将基于计时器值触发映射的systemd单元服务文件。

[root@centos-8 ~]# systemctl enable run-script-with-delay.timer
Created symlink /etc/systemd/system/default.target.wants/run-script-with-delay.timer → /etc/systemd/system/run-script-with-delay.timer.

接下来,重新启动该节点。

验证systemd单元文件配置

重新启动后,当我们检查run-script-with-delay.timer的状态时,在此处观察突出显示的部分,其中显示了计划在5分钟后计划的下一个触发器,我们在计时器单位文件中使用OnBootSec配置了该触发器。

[root@centos-8 ~]# systemctl status run-script-with-delay.timer
● run-script-with-delay.timer - "Run script after 5 minutes of boot"
   Loaded: loaded (/etc/systemd/system/run-script-with-delay.timer; enabled; vendor preset: disabled)
   Active: active (waiting) since Thu 2017-01-16 14:34:34 IST; 27s ago
  Trigger: Thu 2017-01-16 14:39:30 IST; 4min 27s left

达到触发时间后,服务将执行其定义的任务,即在启动5分钟后运行脚本。
如我们现在所见,触发器显示为不适用于计时器单位

[root@centos-8 ~]# systemctl status run-script-with-delay.timer
● run-script-with-delay.timer - "Run script after 5 minutes of boot"
   Loaded: loaded (/etc/systemd/system/run-script-with-delay.timer; enabled; vendor preset: disabled)
   Active: active (elapsed) since Thu 2017-01-16 14:34:34 IST; 5min ago
  Trigger: n/a
Jan 16 14:34:34 centos-8.example.com systemd[1]: Started "Run script after 5 minutes of boot".

还要验证我们输出文件的内容。

[root@centos-8 ~]# cat /tmp/file
Hello hynman, I am running late

因此,正如预期的那样,在系统启动5分钟后不使用任何cron作业的情况下调用了我们的脚本/tmp/delay_script.sh