如何在CentOS/RHEL 7/8中的登录提示之前使用systemd运行脚本

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

在本文中,我将在CentOS/RHEL 7/8 Linux上的登录提示之前,共享示例和示例systemd单元服务文件,以在systemd之前运行脚本。
使用此systemd单元文件,我们可以在Linux引导时将某些命令或者脚本作为最后的服务运行。

理想情况下,我们希望在引导时调用的最后一项服务是getty进程,该进程负责在Linux控制台上显示登录提示。
因此,这里我们的要求基本上是使用systemd执行脚本,该脚本应在getty进程之前调用。

我将使用CentOS/RHEL 7/8 Linux节点来验证本文中的步骤,以在登录提示之前立即使用systemd运行脚本。

第1步:systemd概述

希望我们已经熟悉以下主题

  • systemd概述以及它与旧版SysV脚本的区别

  • 如何在Linux中创建systemd单位文件

创建示例脚本

现在,要在登录提示符前立即使用systemd运行脚本,我们需要一个脚本或者命令。
为了本文的目的,我创建了一个虚拟的shell脚本/tmp/script.sh,我们将使用它来测试本文。
我知道脚本很脏,但是让我们专注于本文的主要议程,因为它可以达到目的。

[root@centos-8 ~]# cat /tmp/script.sh
#!/bin/bash
# Run script with systemd right before login prompt
case  in
        start)
        systemctl list-jobs >> /tmp/file
        echo "====================" >> /tmp/file
        systemctl list-jobs | egrep -q 'getty.target.*start' && echo "starting script before login prompt" >> /tmp/file
		exit 0
        ;;
esac
  • 一旦调用该脚本,它将列出当前活动的作业和目标。
    因此,使用此命令,我们将知道要启动或者正在运行的管道中的服务和目标的列表。

  • 因此,如果我们计划启动" getty.target",那么我们的脚本会将"登录提示前的启动脚本"回显到临时文件"/tmp/file"中。

  • 我们没有明确添加停止功能,因为本文不需要。

提供脚本的可执行权限

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

创建单元文件以在登录提示符前立即使用systemd运行脚本

现在,如第1步中突出显示的那样,我已经写了另一篇文章,其中包含创建新的systemd单元文件的步骤。
其中我们将系统单位文件命名为/etc/systemd/system下的run-before-login-prompt.service
以下是" run-before-login-prompt.service"的内容

[root@centos-8 ~]# cat /etc/systemd/system/run-before-login-prompt.service
[Unit]
Description=Run script with systemd right before login prompt
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/tmp/script.sh start
[Install]
WantedBy=multi-user.target

这里的主要任务是由systemd.unit中的Before =After =指令完成的

Before=, After=
           These two settings expect a space-separated list of unit names. They configure ordering dependencies
           between units. If a unit foo.service contains a setting Before=bar.service and both units are being
           started, bar.service's start-up is delayed until foo.service has finished starting up.

刷新systemd配置文件

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

启用服务以在下次启动时自动启动

[root@centos-8 system]# systemctl enable run-before-login-prompt.service
Created symlink /etc/systemd/system/multi-user.target.wants/run-before-login-prompt.service → /etc/systemd/system/run-before-login-prompt.service.

验证systemd单元文件配置

现在,既然我们完成了systemd的设置。
让我们验证我们的配置。
我们将重启节点并在重启后检查/tmp/file的内容

[root@centos-8 ~]# reboot
login as: root
[email protected]'s password:
Last login: Thu Jan 16 11:01:16 2017 from 10.0.2.2

接下来验证/tmp/file的内容

[root@centos-8 ~]# cat /tmp/file
JOB UNIT                                 TYPE  STATE
259 tuned.service                        start running
232 NetworkManager-wait-online.service   start running
236 vdo.service                          start running
231 network-online.target                start waiting
129 multi-user.target                    start waiting
243 libvirtd.service                     start waiting
230 rpc-statd-notify.service             start waiting
220 systemd-update-utmp-runlevel.service start waiting
265 getty.target                         start waiting
270 systemd-logind.service               start running
218 run-before-login-prompt.service      start running
217 kdump.service                        start waiting
279 rsyslog.service                      start waiting
274 filebeat.service                     start waiting
14 jobs listed.
====================
starting script before login prompt

因此,正如预期的那样,我们能够在登录提示之前立即使用systemd运行脚本。
目前,计划启动14个工作,其中几个服务处于运行状态,包括" run-before-login-prompt.service"等。
由于我们在getty.target之前添加了start的依赖项,因此在登录提示出现之前(即,在getty.target进入运行状态之前)调用了脚本。

说明:

引导后,使用systemd-analyze plot> file.svg生成引导过程的镜像以进行检查。
我们可以使用任何浏览器来查看此file.svg并验证启动过程。
在run-before-login-prompt.service之后,可能会有一两个短暂的服务开始。
如果这是一个问题,请修改/etc/systemd/system/run-before-login-prompt.service来设置Type = idle