如何在Systemd中使用Shell脚本创建和运行新的服务

  • Post author:
  • Post category:其他


本文介绍在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

我的脚本已经启动并且运行。



版权声明:本文为yuyuyuliang00原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。