如何编写头文件 Systemd 服务文件

拒绝访问 | www. | 百度云加速
请打开cookies.
此网站 (www.) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3aad-ua98).
重新安装浏览器,或使用别的浏览器Systemd服务简介-技术 ◆ 学习|Linux.中国-开源社区
Systemd服务简介
systemd 是 Linux 下一个与 SysV 和 LSB 初始化脚本兼容的系统和服务管理器。systemd 使用 socket 和 D-Bus 来开启服务,提供基于守护进程的按需启动策略,保留了 Linux cgroups 的进程追踪功能,支持快照和系统状态恢复,维护挂载和自挂载点,实现了各服务间基于从属关系的一个更为精细的逻辑控制,拥有前卫的并行性能。systemd 无需经过任何修改便可以替代 sysvinit 。
查看和控制systemd的主要命令是systemctl。该命令可用于查看系统状态和管理系统及服务。详见man 1 systemctl。
小贴士:&在&systemctl&参数中添加&-H &用户名&@&主机名&&可以实现对其他机器的远程控制。该过程使用&SSH&链接。注意:&systemadm&是 systemd 的官方图形前端。由&AUR&中的软件包&systemd-ui-git&提供。
输出激活的单元:
$ systemctl
以下命令等效:
$ systemctl list-units
输出运行失败的单元:
$ systemctl --failed
所有可用的单元文件存放在&/usr/lib/systemd/system/&和&/etc/systemd/system/&目录(后者优先级更高)。查看所有已安装服务:
$ systemctl list-unit-files
一个单元配置文件可以描述如下内容之一:系统服务(.service)、挂载点(.mount)、sockets(.sockets&、系统设备、交换分区/文件、启动目标(target)、文件系统路径、由 systemd 管理的计时器。详情参阅&man 5 systemd.unit.
使用&systemctl&控制单元时,通常需要使用单元文件的全名,包括扩展名(例如&sshd.service)。但是有些单元可以在systemctl中使用简写方式。
如果无扩展名,systemctl 默认把扩展名当作&.service。例如&netcfg&和&netcfg.service&是等价的。
挂载点会自动转化为相应的&.mount&单元。例如&/home&等价于&home.mount。
设备会自动转化为相应的&.device&单元,所以&/dev/sda2&等价于&dev-sda2.device。
立即激活单元:
# systemctl start &单元&
立即停止单元:
# systemctl stop &单元&
重启单元:
# systemctl restart &单元&
命令单元重新读取配置:
# systemctl reload &单元&
输出单元运行状态:
$ systemctl status &单元&
检查单元是否配置为自动启动:
$ systemctl is-enabled &单元&
开机自动激活单元:
# systemctl enable &单元&
注意:&如果服务没有Install段落,一般意味着应该通过其它服务自动调用它们。如果真的需要手动安装,可以直接连接服务,如下(将foo替换为真实的服务名):
# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/
取消开机自动激活单元:
# systemctl disable &单元&
显示单元的手册页(必须由单元文件提供):
# systemctl help &单元&
重新载入 systemd,扫描新的或有变动的单元:
# systemctl daemon-reload
安装&polkit&后才可使用电源管理。
如果你正登录在一个本地的systemd-logind用户会话,且当前没有其它活动的会话,那么以下命令无需root权限即可执行。否则(例如,当前有另一个用户登录在某个tty),systemd 将会自动请求输入root密码。
$ systemctl reboot
退出系统并停止电源:
$ systemctl poweroff
$ systemctl suspend
$ systemctl hibernate
混合休眠模式(同时休眠到硬盘并待机):
$ systemctl hybrid-sleep
注意:&可能需要手动创建某些文件。所有文件的权限都是644,属主 root,属组 root。
可以用/etc/vconsole.conf&文件或者localectl&配置虚拟控制台,包括键盘布局和控制台字体。详情请访问&控制台字体&和&键盘布局。
systemd&默认硬件时钟为协调世界时(UTC)。
小贴士:&推荐使用NTP服务来在线同步硬件时钟。
将硬件时钟配置为地方时(不建议):
# timedatectl set-local-rtc true
重新调整为 UTC:
# timedatectl set-local-rtc false
如果设置成本地时间,处理夏令时有些麻烦。如果夏令时调整发生在关机时,下次启动时时间会出现问题()。最新的内核直接从实时时钟芯片(RTC)读取时间,不使用&hwclock,内核把从 RTC 读取的时间当作 UTC 处理。所以如果硬件时间是地方时,系统启动一开始识别的时间是错误的,之后很快会进行矫正。这可能导致一些问题(尤其是时间倒退时)。
如果同时安装了 Windows 操作系统(),那么一般 RTC 会被设置为地方时。Windows 其实也能处理 UTC,需要修改注册表。建议让 Windows 使用 UTC,而非让 Linux 使用地方时。Windows 使用 UTC 后,请记得禁用 Windows 的时间同步功能,以防 Windows 错误设置硬件时间。如上文所说,Linux 可以使用NTP服务来在线同步硬件时钟。
详情参阅&。
默认行为是:在启动一个需要挂载特定分区的服务之前,系统自动检查并挂载分区。/etc/fstab&中设定的网络文件系统(如&NFS、Samba)无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。
详情参阅:man 5 systemd.mount。
如果装有不通过&initramfs&激活的LVM卷,则需启动&lvm-monitoring&服务(由&lvm2&软件包提供):
# systemctl enable lvm-monitoring
/usr/lib/tmpfiles.d/&和&/etc/tmpfiles.d/&中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录,这些文件和目录通常存放在&/run&和&/tmp&中。配置文件名称为&/etc/tmpfiles.d/&program&.conf。此处的配置能覆盖&/usr/lib/tmpfiles.d/&目录中的同名配置。
临时文件通常和服务文件同时提供,以生成守护进程需要的文件和目录。例如&Samba&服务需要目录&/run/samba&存在并设置正确的权限位,就象这样:
/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root
此外,临时文件还可以用来在开机时向特定文件写入某些内容。比如,要禁止系统从USB设备唤醒,利用旧的&/etc/rc.local&可以用&echo USBE & /proc/acpi/wakeup,而现在可以这么做:
/etc/tmpfiles.d/disable-usb-wake.conf
w /proc/acpi/wakeup - - - - USBE
详情参见&man 5 tmpfiles.d。
注意:&该方法不能向&/sys&中的配置文件添加参数,因为&systemd-tmpfiles-setup&有可能在相关模块加载前运行。这种情况下,需要首先通过&modinfo &模块名&&确认需要的参数,并在&/etc/modprobe.d&下的一个文件中设置改参数。另外,还可以使用&udev 规则,在设备就绪时设置相应属性。
systemd 的单元文件是受 XDG Desktop Entry .desktop 文件启发而产生,而最初起源是 Windows 下的 .ini 文件。
示例参见:Systemd/Services。
使用systemd时,可通过正确编写单元配置文件来解决其依赖关系。典型的情况是,单元A要求单元B在A启动之前运行。在此情况下,向单元A配置文件中的&[Unit]&段添加&Requires=B&和&After=B&即可。若此依赖关系是可选的,可添加&Wants=B&和&After=B。请注意&Wants=&和&Requires=&并不意味着&After=,即如果&After=&选项没有制定,这两个单元将被并行启动。
依赖关系通常被用在服务(service)而不是目标(target)上。例如,&network.target&一般会被某个配置网络接口的服务引入,所以,将自定义的单元排在该服务之后即可,因为&network.target&已经启动。
编写自定义的 service 文件时,可以选择几种不同的服务启动方式。启动方式可通过配置文件&[Service]&段中的&Type=&参数进行设置。具体的参数说明请参阅&man systemd.service&。
Type=simple(默认值):systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket激活型。
Type=forking:systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定&PIDFile=,以便systemd能够跟踪服务的主进程。
Type=oneshot:这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置&RemainAfterExit=yes&使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
Type=notify:与&Type=simple&相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由&libsystemd-daemon.so&提供。
Type=dbus:若以此方式启动,当指定的&BusName&出现在DBus系统总线上时,systemd认为服务就绪。
要更改由软件包提供的单元文件,先创建名为&/etc/systemd/system/&单元名&.d/&的目录(如&/etc/systemd/system/httpd.service.d/),然后放入&*.conf&文件,其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。例如,如果想添加一个额外的依赖,创建这么一个文件即可:
/etc/systemd/system/&unit&.d/customdependency.conf
Requires=&新依赖&
After=&新依赖&
然后运行以下命令使更改生效:
# systemctl daemon-reload
# systemctl restart &单元&
此外,把旧的单元文件从&/usr/lib/systemd/system/&复制到&/etc/systemd/system/,然后进行修改,也可以达到同样效果。在&/etc/systemd/system/&目录中的单元文件的优先级总是高于&/usr/lib/systemd/system/&目录中的同名单元文件。注意,当&/usr/lib/&中的单元文件因软件包升级变更时,/etc/&中自定义的单元文件不会同步更新。此外,你还得执行&systemctl reenable &unit&,手动重新启用该单元。因此,建议使用前面一种利用&*.conf&的方法。
小贴士:&可以用&systemd-delta&命令来查看哪些单元文件被覆盖、哪些被修改。
可从&官方仓库&安装&vim-systemd&软件包,使 unit 配置文件在&Vim&下支持语法高亮。
启动级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和启动级别功能相似又不同的概念&&目标(target)。不像数字表示的启动级别,每个目标都有名字和独特的功能,并且能同时启用多个。一些目标继承其他目标的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 启动级别的目标,仍可以使用旧的&telinit 启动级别&命令切换。
不要使用&runlevel&命令了:
$ systemctl list-units --type=target
在 Fedora 中,启动级别 0、1、3、5、6 都被赋予特定用途,并且都对应一个 systemd 的目标。然而,没有什么很好的移植用户定义的启动级别(2、4)的方法。要实现类似功能,可以以原有的启动级别为基础,创建一个新的目标&/etc/systemd/system/&新目标&(可以参考&/usr/lib/systemd/system/graphical.target),创建&/etc/systemd/system/&新目标&.wants&目录,向其中加入额外服务的链接(指向&/usr/lib/systemd/system/&中的单元文件)。
SysV 启动级别Systemd 目标注释
runlevel0.target, poweroff.target
中断系统(halt)
1, s, single
runlevel1.target, rescue.target
单用户模式
runlevel2.target, runlevel4.target, multi-user.target
用户自定义启动级别,通常识别为级别3。
runlevel3.target, multi-user.target
多用户,无图形界面。用户可以通过终端或网络登录。
runlevel5.target, graphical.target
多用户,图形界面。继承级别3的服务,并启动图形界面服务。
runlevel6.target, reboot.target
emergency.target
急救模式(Emergency shell)
systemd 中,启动级别通过&目标单元&访问。通过如下命令切换:
# systemctl isolate graphical.target
该命令对下次启动无影响。等价于telinit 3&或&telinit 5。
开机启动进的目标是&default.target,默认链接到&graphical.target&(大致相当于原来的启动级别5)。可以通过内核参数更改默认启动级别:
小贴士:&可以省略扩展名&.target。
systemd.unit=multi-user.target&(大致相当于级别3)
systemd.unit=rescue.target&(大致相当于级别1)
另一个方法是修改&default.target。可以通过&systemctl&修改它:
# systemctl enable multi-user.target
命令执行情况由&systemctl&显示:链接&/etc/systemd/system/default.target&被创建,指向新的默认启动级别。该方法当且仅当目标配置文件中有以下内容时有效:
Alias=default.target
目前,multi-user.target、graphical.target&都包含这段内容。
systemd 提供了自己日志系统(logging system),称为 journal. 使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:
# journalctl
默认情况下(当&Storage=&在文件&/etc/systemd/journald.conf&中被设置为&auto),日志记录将被写入&/var/log/journal/。该目录是&&软件包的一部分。若被删除,systemd&不会自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入&/run/systemd/journal。这意味着,系统重启后日志将丢失。
journalctl可以根据特定字段过滤输出,例如:
显示本次启动后的所有日志:
# journalctl -b
不过,一般大家更关心的不是本次启动后的日志,而是上次启动时的(例如,刚刚系统崩溃了)。目前还没有这项功能,正在&systemd-devel@lists.freedesktop.org&讨论中。
目前的折中方案是:
# journalctl --since=today | tac | sed -n '/-- Reboot --/{n;:r;/-- Reboot --/q;p;n;b r}' | tac
以上命令输出本日内的所有启动信息。但要注意,如果日志很多,该命令执行时间会比较漫长。
动态跟踪最新信息:
# journalctl -f
显示特定程序的所有消息:
# journalctl /usr/lib/systemd/systemd
显示特定进程的所有消息:
# journalctl _PID=1
显示指定单元的所有消息:
# journalctl -u netcfg
详情参阅man journalctl、man systemd.journal-fields,以及 Lennert 的这篇。
如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果&/var/log/journal&储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改&/etc/systemd/journald.conf中的&SystemMaxUse&来指定该最大限制。如限制日志最大 50MiB:
SystemMaxUse=50M
详情参见&man journald.conf.
systemd 提供了 socket&/run/systemd/journal/syslog,以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非&/dev/log()。Arch 软件仓库中的&syslog-ng&已经包含了需要的配置。
设置开机启动 syslog-ng:
# systemctl enable syslog-ng
有一份很不错的&journalctl&指南。
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读,确认你是否是该问题受害者。
若&journalctl -u foounit.service&没有显示某个短时进程的任何输出,那么改用 PID 试试。例如,若&systemd-modules-load.service&执行失败,那么先用&systemctl status systemd-modules-load&查询其 PID(比如是123),然后检索该 PID 相关的日志&journalctl -b _PID=123。运行时进程的日志元数据(诸如 _SYSTEMD_UNIT 和 _COMM)被乱序收集在&/proc&目录。要修复该问题,必须修改内核,使其通过套接字连接来提供上述数据,该过程类似于 SCM_CREDENTIALS。
使用如下内核参数引导:&systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M
更多有关调试的信息,参见。
要使用老的内核转储,创建下面文件:
/etc/sysctl.d/49-coredump.conf
kernel.core_pattern = core
kernel.core_uses_pid = 0
然后运行:
# /usr/lib/systemd/systemd-sysctl
同样可能需要执行&unlimit&设置文件大小:
$ ulimit -c unlimited
更多信息请参阅&&和&。
The H Open&杂志上的科普文章博客分类:
输出激活的单元:
$ systemctl
以下命令等效:
$ systemctl list-units
输出运行失败的单元:
$ systemctl --failed
所有可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录(后者优先级更高)。查看所有已安装服务:
$ systemctl list-unit-files
立即激活单元:
# systemctl start &单元&
立即停止单元:
# systemctl stop &单元&
重启单元:
# systemctl restart &单元&
重新加载配置:
# systemctl reload &单元&
输出单元运行状态:
$ systemctl status &单元&
检查单元是否配置为自动启动:
$ systemctl is-enabled &单元&
开机自动激活单元:
# systemctl enable &单元&
取消开机自动激活单元:
# systemctl disable &单元&
显示单元的手册页(必须由单元文件提供):
# systemctl help &单元&
重新载入 systemd,扫描新的或有变动的单元:
# systemctl daemon-reload
编写systemd下服务脚本
Red Hat Enterprise Linux 7(RHEL 7)已经将服务管理工具从SysVinit和Upstart迁移到了systemd上,相应的服务脚本也需要改变。前面的版本里,所有的启动脚本都是放在/etc/rc.d/init.d/ 目录下。这些脚本都是bash脚本,可以让系统管理员控制这些服务的状态,通常,这些脚本中包含了start,stop,restart这些方法,以提供系统自动调用这些方法。但是在RHEL 7中当中已经完全摒弃了这种方法,而采用了一种叫unit的配置文件来管理服务。
■Systemd下的unit文件
Unit文件专门用于systemd下控制资源,这些资源包括服务(service)、套接字(socket)、设备(device)、挂载点(mount point)、自动挂载点(automount point)、交换文件或分区(a swap file or partition)…
所有的unit文件都应该配置[Unit]或者[Install]段.由于通用的信息在[Unit]和[Install]中描述,每一个unit应该有一个指定类型段,例如[Service]来对应后台服务类型unit.
unit 类型如下:
service :守护进程的启动、停止、重启和重载是此类 unit 中最为明显的几个类型。
socket :此类 unit 封装系统和互联网中的一个socket。当下,systemd支持流式, 数据报和连续包的AF\_INET,AF\_INET6,AF\_UNIXsocket 。也支持传统的 FIFOs 传输模式。每一个 socket unit 都有一个相应的服务 unit 。相应的服务在第一个“连接”进入 socket 或 FIFO 时就会启动(例如:nscd.socket 在有新连接后便启动 nscd.service)。
device :此类 unit 封装一个存在于 Linux设备树中的设备。每一个使用 udev 规则标记的设备都将会在 systemd 中作为一个设备 unit 出现。udev 的属性设置可以作为配置设备 unit 依赖关系的配置源。
mount :此类 unit 封装系统结构层次中的一个挂载点。
automount :此类 unit 封装系统结构层次中的一个自挂载点。每一个自挂载 unit 对应一个已挂载的挂载 unit (需要在自挂载目录可以存取的情况下尽早挂载)。
target :此类 unit 为其他 unit 进行逻辑分组。它们本身实际上并不做什么,只是引用其他 unit 而已。这样便可以对 unit 做一个统一的控制。(例如:multi-user.target 相当于在传统使用 SysV 的系统中运行级别5);bluetooth.target 只有在蓝牙适配器可用的情况下才调用与蓝牙相关的服务,如:bluetooth 守护进程、obex 守护进程等)
snapshot :与 targetunit 相似,快照本身不做什么,唯一的目的就是引用其他 unit 。
■认识service的unit文件
扩展名:.service
路径:
&&&& /etc/systemd/system/*&&&& ――――& 供系统管理员和用户使用
&&&&& /run/systemd/system/*&&&& ――――& 运行时配置文件
&&&&& /usr/lib/systemd/system/*&& ――――& 安装程序使用(如RPM包安装)
以下是一段service unit文件的例子,属于/usr/lib/systemd/system/NetworkManager.service文件,它描述的是系统中的网络管理服务。
Description=Network Manager
Wants=network.target
Before=network.target network.service
BusName=org.freedesktop.NetworkManager
ExecStart=/usr/sbin/NetworkManager --no-daemon
# NM doesn't want systemd to kill its children for it
KillMode=process
WantedBy=multi-user.target
Alias=dbus-org.freedesktop.NetworkManager.service
Also=NetworkManager-dispatcher.service
整个文件分三个部分,[Unit]·[Service]·[Install]
[Unit]:记录unit文件的通用信息。
[Service]:记录Service的信息
[Install]:安装信息。
Unit主要包含以下内容:
●& Description:对本service的描述。
●& Before, After:定义启动顺序,Before=xxx.service,代表本服务在xxx.service启动之前启动。After=xxx.service,代表本服务在xxx之后启动。
●& Requires: 这个单元启动了,那么它“需要”的单元也会被启动; 它“需要”的单元被停止了,它自己也活不了。但是请注意,这个设定并不能控制某单元与它“需要”的单元的启动顺序(启动顺序是另外控制的),即 Systemd 不是先启动 Requires 再启动本单元,而是在本单元被激活时,并行启动两者。于是会产生争分夺秒的问题,如果 Requires 先启动成功,那么皆大欢喜; 如果 Requires 启动得慢,那本单元就会失败(Systemd 没有自动重试)。所以为了系统的健壮性,不建议使用这个标记,而建议使用 Wants 标记。可以使用多个 Requires。
●& RequiresOverridable:跟 Requires 很像。但是如果这条服务是由用户手动启动的,那么 RequiresOverridable 后面的服务即使启动不成功也不报错。跟 Requires 比增加了一定容错性,但是你要确定你的服务是有等待功能的。另外,如果不由用户手动启动而是随系统开机启动,那么依然会有 Requires 面临的问题。
●& Requisite:强势版本的 Requires。要是这里需要的服务启动不成功,那本单元文件不管能不能检测等不能等待都立刻就会失败。
●& Wants:推荐使用。本单元启动了,它“想要”的单元也会被启动。但是启动不成功,对本单元没有影响。
●& Conflicts:一个单元的启动会停止与它“冲突”的单元,反之亦然。
Service主要包含以下内容:
●& Type:service的种类,包含下列几种类型:
&&&&&&&&&&& ----simple 默认,这是最简单的服务类型。意思就是说启动的程序就是主体程序,这个程序要是退出那么一切都退出。
&&&&&&&&&& -----forking 标准 Unix Daemon 使用的启动方式。启动程序后会调用 fork() 函数,把必要的通信频道都设置好之后父进程退出,留下守护精灵的子进程
&&&&&&&&&& -----oneshot种服务类型就是启动,完成,没进程了。
notify,idle类型比较少见,不介绍。
●& ExecStart:服务启动时执行的命令,通常此命令就是服务的主体。
&&&&&&& ------如果你服务的类型不是 oneshot,那么它只可以接受一个命令,参数不限。
&&&&&& ------多个命令用分号隔开,多行用 \ 跨行。
●& ExecStartPre, ExecStartPost:ExecStart执行前后所调用的命令。
●& ExecStop:定义停止服务时所执行的命令,定义服务退出前所做的处理。如果没有指定,使用systemctl stop xxx命令时,服务将立即被终结而不做处理。
●& Restart:定义服务何种情况下重启(启动失败,启动超时,进程被终结)。可选选项:no, on-success, on-failure,on-watchdog, on-abort
●& SuccessExitStatus:参考ExecStart中返回值,定义何种情况算是启动成功。
&&& eg:SuccessExitStatus=1 2 8 SIGKILL
Install主要包含以下内容:
●& WantedBy:何种情况下,服务被启用。
&&& eg:WantedBy=multi-user.target(多用户环境下启用)
●& Alias:别名
■旧的命令与systemd命令的映射
service systemctl Description
service name start&&& ----&& systemctl start name.service&& ●Starts a service.
service name stop&& ----&& systemctl stopname.service&& ●Stops a service.
service name restart& ----&& systemctl restartname.service& ●Restarts a service.
service name condrestart ----&
systemctl try-restart name.service ●Restarts a service only if it is running.
service name reload& ----&& systemctl reloadname.serviceReloads configuration.
service name status ----&& systemctl status name.service
systemctl is-active name.service
●Checks if a service isrunning.
service --status-all& ----& systemctl list-units –type service --all
●Displays the status of all services.chkconfig systemctl
chkconfig name on& ----&&& systemctl enablename.service ●Enables a service.
chkconfig name off&& ----&&& systemctl disablename.service ●Disables a service.
chkconfig --list name& ----&& systemctl statusname.service
system ctl is-enabled name.service
●Checks if a service is enabled.
chkconfig --list& ----& systemctl list-unit-files –type service
●Lists all services and checks if they are enabled.
■创建自己的systemd服务
弄清了unit文件的各项意义,我们可以尝试编写自己的服务,与以前用SysV来编写服务相比,整个过程比较简单。unit文件有着简洁的特点,是以前臃肿的脚本所不能比的。
在本例中,尝试写一个命名为my-demo.service的服务,整个服务很简单:在开机的时候将服务启动时的时间写到一个文件当中。可以通过这个小小的例子来说明整个服务的创建过程。
Step1:编写属于自己的unit文件,命令为my-demo.service,整个文件如下:
[Unit]
Description=My-demo Service
Type=oneshot
ExecStart=/bin/bash /root/test.sh
StandardOutput=syslog
StandardError=inherit
WantedBy=multi-user.target
Step2:将上述的文件拷贝到RHEL 7系统中/usr/lib/systemd/system/*目录下
Step3:编写unit文件中ExecStart=/bin/bash /root/test.sh所定义的test.sh文件,将其放在定义的目录当中,此文件是服务的执行主体。文件内容如下:
#!/bin/bash
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
date && /tmp/date
Step4:将my-demo.service注册到系统当中执行命令:
# systemctl enable my-demo.service
输出:ln -s'/usr/lib/systemd/system/my-demo.service' '/etc/systemd/system/multi-user.target.wants/my-demo.service'
输出表明,注册的过程实际上就是将服务链接到/etc/systemd/system/目录下。
至此服务已经创建完成。重新启动系统,会发现/tmp/date文件已经生成,服务在开机时启动成功。当然本例当中的test.sh文件可以换成任意的可执行文件作为服务的主体,这样就可以实现各种各样的功能。
浏览: 1132460 次
来自: 珠海
很有用,谢谢
厉害,困扰了我很久
非常好,很实用啊。。
你好,你能把能讓這個程序的運行起來的代碼發我一下嗎?非常著急需 ...
可能配置有问题.
这文章我只是收藏转发而已, 并没有实 ...

我要回帖

更多关于 如何编写头文件 的文章

 

随机推荐