使用Systemd CentOS/RHEL 7/8启动N分钟后如何运行脚本
在本文中,我将共享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
。