如何使用 Shell 脚本在 Systemd 中创建和运行新的服务单元
几天前,我偶然发现了一个Centos 8 32 位发行版,我想在一台旧的 32 位机器上测试一下。启动后,我发现它有一个错误,网络连接丢失了,每次启动后我都必须手动将其“打开”。那么,问题是,我如何设置一个脚本来完成这项工作,并在每次启动机器时运行?
好吧,这很简单,我将向您展示使用服务单元的系统方式。但首先要对服务单元进行简要介绍。
在本文中,我将解释systemd 中的“服务单元”是什么,以及创建和运行服务单元有多么容易。我将尝试简化“目标”是什么、为什么我们称它们为“单元集合”以及它们的“需求”是什么。最后,我们将利用服务单元在启动过程后运行我们自己的脚本。
显然,您的计算机因其提供的服务而有用,并且为了拥有此功能,必须在计算机启动并达到不同级别时调用许多服务。
例如,当计算机达到救援级别 (运行级别 0 ) 时,将调用其他服务来执行;当计算机达到多用户级别 (运行级别 3 ) 时,将调用其他服务来执行。您可以将这些级别想象为目标。
简单来说,target是服务单元的集合。如果你想查看在graphic.target级别运行的服务单元,请输入:
# systemctl --type=service
如您所见,一些服务始终处于活动状态并“运行”,而其他服务则运行一次并终止(退出)。
如果您想检查服务的状态,可以使用systemctl 命令,如下所示。
# systemctl status firewalld.service
如您所见,我检查了firewalld.service
(提示:您可以使用自动完成功能来输入服务名称)的状态。它通知我,firewalld服务一直在运行,并且已启用。
启用和禁用分别表示服务在下次启动时是否永久加载。另一方面,启动和停止服务有当前会话的限制,并且不是永久的。
例如,如果您输入:
# systemctl stop firewalld.service # systemctl status firewalld.service
您可以看到,它firewalld.service
处于非活动状态(已停止),但仍处于启用状态,这意味着在下次启动时它将被加载。因此,如果我们希望将来在启动时加载服务,我们必须启用它。多么好的结论!让我们创建一个,这很容易。
如果你进入该文件夹:
# cd /etc/systemd/system # ls -l
您可以看到一些单元服务的链接文件和一些目标“需要”的目录。例如,当引导过程达到其级别时,多用户目标需要加载的内容列在名为/etc/systemd/system/multi-user.target.wants/的目录中。
# ls multi-user.target.wants/
如您所见,它不仅包含服务,还包含其他目标,这些目标也是服务的集合。
让我们创建一个名为connection.service 的服务单元。
# vim connection.service
并输入以下内容(点击“i”
进入插入模式),保存并退出(使用“esc”
和“:wq!”
):
[Unit] Description = making network connection up After = network.target [Service] ExecStart = /root/scripts/conup.sh [Install] WantedBy = multi-user.target
解释上述内容:我们创建了一个服务类型的单元(您也可以创建目标类型的单元),并将其设置为在 network.target 之后加载(您可以理解为启动过程按照定义的顺序到达目标),并且我们希望每次服务启动时都执行我们将要创建的名为conup.sh的 bash 脚本。
有趣的是从最后一部分[install]开始的。它告诉我们它将被“multi-user.target”所需要。因此,如果我们启用我们的服务,则会在multi-user.target.wants文件夹中创建指向该服务的符号链接!明白了吗?如果我们禁用它,该链接将被删除。就这么简单。
只需启用它并检查:
# systemctl enable connection.service
它告诉我们multi-user.target.wants文件夹中的符号链接已创建。您可以通过运行ls 命令来确认,如下所示。
# ls multi-user.target.wants/
如您所见,“connection.service”已准备好进行下一次启动,但我们必须先创建脚本文件。
# cd /root # mkdir scripts # cd scripts # vim conup.sh
在Vim中添加以下行并保存:
#!/bin/bash nmcli connection up enp0s3
nmcli 命令用于为enp0s3接口建立网络连接。
当然,如果您希望脚本执行其他操作,您可以输入任何您想要的内容而不是第二行。
例如,
#!/bin/bash touch /tmp/testbootfile
这会在/tmp文件夹中创建一个文件(只是为了检查您的服务是否正常运行)。
我们还必须通过运行chmod命令使脚本可执行,如下所示。
# chmod +x conup.sh
现在我们准备好了。如果你不想等到下次启动(它已经启用),我们可以通过输入以下内容来启动当前会话的服务:
# systemctl start connection.service
瞧!我的连接已建立并运行!
如果您选择在脚本中写入命令“touch /tmp/testbootfile” ,只是为了检查其功能,您将看到在/tmp文件夹中创建了此文件。
我真的希望能帮助您弄清楚启动期间的服务、需求、目标和运行脚本的全部内容。