本文介绍在systemd中一个”service unit”是什么,要创建和运行一个”service unit”多简单。我尝试简化”targets”是什么,为什么我们称它们”collections of units”并且它们的”wants”是什么。最后我们利用一个服务单元在系统系统过程后运行我们自己的脚本。
很明显因为你计算机提供的服务,所以它是有用的,并且为了有这个功能,当计算机启动并且到达了不同级别,必须调用很多服务。当计算机到达了例如救援级别(runlevel 0)时,调用执行其它服务,而当它达到多用户级别时(runlevel 3)时,调用执行其它服务。你可以设想这些级别为targets。
用一个简单方式,目标是一个服务单元的集合。如果查看在你的multi-user级别中运行的服务单元,输入:
[root@telecom ~]# systemctl --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
auditd.service loaded active running Security Auditing Service
...
rpcbind.service loaded active running RPC bind service
rsyslog.service loaded active running System Logging Service
如你所见,我检查了smb.service的状态(提示:你可以使用服务名称自动补全)。它告诉我smb服务一直运行并且它被启用了:
[root@telecom ~]# systemctl status smb.service
● smb.service - Samba SMB Daemon
Loaded: loaded (/usr/lib/systemd/system/smb.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2022-08-28 17:34:33 CST; 15h ago
Docs: man:smbd(8)
man:samba(7)
man:smb.conf(5)
Main PID: 1162 (smbd)
Status: "smbd: ready to serve connections..."
CGroup: /system.slice/smb.service
├─1162 /usr/sbin/smbd --foreground --no-process-group
├─1363 /usr/sbin/smbd --foreground --no-process-group
├─1364 /usr/sbin/smbd --foreground --no-process-group
└─1378 /usr/sbin/smbd --foreground --no-process-group
Aug 28 17:34:32 telecom systemd[1]: Starting Samba SMB Daemon...
Aug 28 17:34:33 telecom smbd[1162]: [2022/08/28 17:34:33.115547, 0] ../../lib/util/become_daemon.c:136(daemon_ready)
Aug 28 17:34:33 telecom systemd[1]: Started Samba SMB Daemon.
Aug 28 17:34:33 telecom smbd[1162]: daemon_ready: daemon 'smbd' finished starting up and ready to serve connections
启用和禁用各自表示这个服务将是否在下次系统启动过程中被永久装载。零一方面,启动或停止一个服务具有当前会话的限制并且它不是永久的。
例如,如果你输入:
[root@telecom ~]# systemctl stop smb.service
[root@telecom ~]# systemctl status smb.service
● smb.service - Samba SMB Daemon
Loaded: loaded (/usr/lib/systemd/system/smb.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Mon 2022-08-29 09:02:57 CST; 10s ago
Docs: man:smbd(8)
man:samba(7)
man:smb.conf(5)
Process: 1162 ExecStart=/usr/sbin/smbd --foreground --no-process-group $SMBDOPTIONS (code=killed, signal=TERM)
Main PID: 1162 (code=killed, signal=TERM)
Status: "smbd: ready to serve connections..."
Aug 28 17:34:32 telecom systemd[1]: Starting Samba SMB Daemon...
Aug 28 17:34:33 telecom smbd[1162]: [2022/08/28 17:34:33.115547, 0] ../../lib/util/become_daemon.c:136(daemon_ready)
Aug 28 17:34:33 telecom systemd[1]: Started Samba SMB Daemon.
Aug 28 17:34:33 telecom smbd[1162]: daemon_ready: daemon 'smbd' finished starting up and ready to serve connections
Aug 29 09:02:57 telecom systemd[1]: Stopping Samba SMB Daemon...
Aug 29 09:02:57 telecom systemd[1]: Stopped Samba SMB Daemon.
你可以看到smb.services是不活跃的(dead),但它仍然是启用的,这表示在下次系统启动中,它将被装载。所以如果我们想要以后再系统启动时一个服务被装载,我们必须启用它。让我们创建一个,它是简单的。
如果我们进入这个文件夹:
[root@telecom system]# cd /etc/systemd/system
[root@telecom system]# ls -l
total 56
drwxr-xr-x. 2 root root 4096 Dec 27 2021 basic.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 cloud-init.target.wants
-rw-r--r--. 1 root root 266 Dec 27 2021 cloudResetPwdAgent.service
-rw-r--r--. 1 root root 294 Dec 27 2021 cloudResetPwdUpdateAgent.service
lrwxrwxrwx. 1 root root 57 Dec 27 2021 dbus-org.freedesktop.nm-dispatcher.service -> /usr/lib/systemd/system/NetworkManager-dispatcher.service
lrwxrwxrwx. 1 root root 37 Dec 27 2021 default.target -> /lib/systemd/system/multi-user.target
drwxr-xr-x. 2 root root 4096 Dec 27 2021 default.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 dev-virtio\x2dports-org.qemu.guest_agent.0.device.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 getty.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 local-fs.target.wants
drwxr-xr-x. 2 root root 4096 Aug 28 23:29 multi-user.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 network-online.target.wants
drwxr-xr-x 2 root root 4096 Aug 20 19:25 remote-fs.target.wants
drwxr-xr-x 2 root root 4096 Aug 20 19:25 sockets.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 sysinit.target.wants
drwxr-xr-x. 2 root root 4096 Dec 27 2021 system-update.target.wants
你可以看到一些单元服务的链接文件和一些一个目录的”wants”的目录。例如,在系统启动过程到达multi-user运行级别时,multi-user目标想要装载什么,在名为/etc/systemd/system/multi-user.target.wants/的目录中被列出。
[root@telecom system]# ls /etc/systemd/system/multi-user.target.wants/
auditd.service irqbalance.service postfix.service rsyslog.service tuned.service
cloudResetPwdAgent.service kdump.service remote-fs.target smb.service webmin.service
cloudResetPwdUpdateAgent.service NetworkManager.service rhel-configure.service sshd.service ypbind.service
crond.service nfs-client.target rpcbind.service testIOC.service
如你所见,它不但包含了services,还包含了其它targets,其也是services的集合。
让我们用connect.service创建一个服务单元。
[root@telecom multi-user.target.wants]# cat connection.service
[Unit]
Description = making
After = network.target
[Service]
ExecStart = /root/scripts/conup.sh
[Install]
WantedBy = multi-user.target
解释以上:我们创建一个service类型的单元(你也可以创建target类的单元),我们设置在network.target后装载它(你能够理解引导过程按一个定义好的顺序达到targets),并且我们想要每次服务启动去执行一个我们将要创建的名为conup.sh的脚本。
这个功能从最后部分[install]开始。它告诉”multi-user.target”将想要它。所以如果我们启动我们的服务,在multi-user.target.wants文件夹内将创建一个指向那个服务的符号链接。理解码?并且如果我们禁用它,将删除这个链接。
只要启用它并且检查:
[root@telecom system]# systemctl enable connection
Created symlink from /etc/systemd/system/multi-user.target.wants/connection.service to /etc/systemd/system/connection.service.
它告诉我们在multi-user.target.wants中已经创建了一个符号链接。检查:
[root@telecom system]# ls -l multi-user.target.wants/connection.service
lrwxrwxrwx 1 root root 38 Aug 29 13:24 multi-user.target.wants/connection.service -> /etc/systemd/system/connection.service
如你看到”connection.service”已经为下次系统启动做好准备,但我们必须首先创建这个脚本文件。
[root@telecom scripts]# cd /root
[root@telecom scripts]# mkdir scripts
[root@telecom scripts]# cd scripts
[root@telecom scripts]# vim conup.sh
[root@telecom scripts]# cat conup.sh
#!/bin/bash
echo `date` >>/tmp/dates.log
如果你想要你的脚本执行另外的事情,你可以输入你想要的任何东西替代第二行。
例如:
[root@telecom scripts]# vim newfile.sh
[root@telecom scripts]# cat newfile.sh
#!/bin/bash
touch /tmp/testbootfile
其将在/tmp文件夹下创建一个文件(检查你的服务有效)。
我们也必须使得这个脚本可执行:
[root@telecom scripts]# chmod +x conup.sh
现在我们准备好了。如果你不想要等到下次系统启动,我们可以输入以下为当前会话启动这个服务:
[root@telecom scripts]# systemctl start connection
[root@telecom scripts]# cat /tmp/dates.log
Mon Aug 29 13:39:59 CST 2022
我的脚本已经启动并且运行。