Linux服务
1、查看服务状态
正确:service networking status 错误:service networking.service status (不要被tab键带偏了) 正确:systemctl status networking 正确:systemctl status networking.service
注意下status在两个命令之间位置的不同。
2、linux服务相关知识
ExecStartPre:服务启动前执行 ExecStart: 服务启动执行
发现,始终解决不了,报unable open display ""错误。 位置和命令确认没有错误,因为在其中添加了rm命令测试正常。
参考:https://blog.csdn.net/weixin_35742493/article/details/121403271
2-1、什么是.service文件?
Linux中.service文件是某项服务对应的配置文件,可用于systemd管理和控制的服务的设置。 .service 文件通常包含3个模块,即[Unit]控制单元,表示启动顺序和依赖关系;[Service]服务,表示服务的定义;[Install]安装,表示如何安装配置文件。
2-2、文件存放位置
.service 文件配置的服务常用systemd管理。然而,systemd有系统和用户区分;系统(/lib/systemd/system/)、用户(/usr/lib/systemd/user/)。一般系统管理员手工创建的单元文件建议存放在/etc/systemd/system/目录下面。
2-3、创建.service 文件
以httpd.service 为例
[Unit]
Description=httpd #当前配置文件的描述信息
After=network.target #表示当前服务是在那个服务后面启动,一般定义为网络服务启动后启动
[Service]
Type=forking #定义启动类型
ExecStart=/usr/local/apache/bin/apachectl start #定义启动进程时执行的命令。
ExecReload=/usr/local/apache/bin/apachectl restart #重启服务时执行的命令
ExecStop=/usr/local/apache/bin/apachectl stop #定义关闭进程时执行的命令。
PrivateTmp=true #是否分配独立空间
[Install]
WantedBy=multi-user.target #表示多用户命令行状态
2-4、[Unit]字段介绍 ——主要给出服务描述、启动顺序和依赖关系
Description:当前服务的简单描述。 Documentation:服务文档 After和Before:表示启动顺序,不涉及依赖关系。Before=xxx.service表示本服务在xxx.service 启动之前启动,After=yyy.service表示本服务在yyy.service 之后启动。 Wants:表示该服务和某服务存在某种弱依赖关系,即某服务停止运行或退出不影响该服务继续运行。 Requires:表示”强依赖”关系,即某服务停止运行或退出,改服务也必须停止运行。 Wants字段与Requires字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动的。
2-5、[Service]字段介绍——服务的启动行为以及如何启动、重启、停止等信息
Type=simple(默认值):systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket激活型。 Type=forking:systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 PIDFile=,以便systemd能够跟踪服务的主进程。 Type=oneshot:这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。Type=oneshot允许指定多个希望顺序执行的用户自定义命令。 Type=notify:与 Type=simple 相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 libsystemd-daemon.so 提供。 Type=dbus:若以此方式启动,当指定的 BusName 出现在DBus系统总线上时,systemd认为服务就绪。 Type=idle: systemd会等待所有任务(Jobs)处理完成后,才开始执行idle类型的单元。除此之外,其他行为和Type=simple 类似。 PIDFile:pid文件路径
ExecStart:指定启动单元的命令或者脚本,ExecStartPre和ExecStartPost节指定在ExecStart之前或者之后用户自定义执行的脚本。 ExecReload:指定单元停止时执行的命令或者脚本。 ExecStop:指定单元停止时执行的命令或者脚本。 PrivateTmp:True表示给服务分配独立的临时空间 Restart:这个选项如果被允许,服务重启的时候进程会退出,会通过systemctl命令执行清除并重启的操作。 RemainAfterExit:如果设置这个选择为真,服务会被认为是在激活状态,即使所以的进程已经退出,默认的值为假,这个选项只有在Type=oneshot时需要被配置。 User字段可以设置服务的用户名 WorkingDirectory字段指定服务的安装目录
2-6、[Install]字段介绍——何安装这个配置文件,即怎样做到开机自启
Alias:为单元提供一个空间分离的附加名字。 RequiredBy:单元被允许运行需要的一系列依赖单元,RequiredBy列表从Require获得依赖信息。 Also:指出和单元一起安装或者被协助的单元。 DefaultInstance:实例单元的限制,这个选项指定如果单元被允许运行默认的实例。 WantedBy字段:表示该服务所在的 Target。 Target的含义是服务组,表示一组服务。 WantedBy=multi-user.target指的是服务所在的Target是multi-user.target
Systemd 有默认的启动 Target就是multi-user.target,在这个组里的所有服务,都将开机启动。
#查看 multi-user.target 包含的所有服务
systemctl list-dependencies multi-user.target
2-7、其它配置文件
如果工程文件需要debian编包,需要在debian文件夹中的install文件中写入.service文件的安装路径,一般放在/usr/lib/systemd/system路径下。同时,如果需要开机自启动,在postinst文件中写入systemctl enable service_name.service。
3、实战
3-1、编写服务
[Unit]
Description=study_service
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/media/hankin/vdb/TransferStation/a.out
ExecReload=/media/hankin/vdb/TransferStation/a.out
KillMode=process
Restart=always
RestartSec=5
#WatchdogSec=10
#LimitCORE=0
[Install]
WantedBy=multi-user.target
将此服务study_service.service文件拷贝到/lib/systemd/system/目录下。 可能需要重启服务守护进程:systemctl daemon-reload
发现/etc/systemd/system/multi-user.target.wants/目录下一般会有一个服务的软链接,暂时不清楚其作用,不添加软链接也能运行。
3-2、编写程序
/**
* 文 件 名: study_service.cpp
* 文件描述: 学习Linux系统的服务及其使用
* 作 者: HanKin
* 创建日期: 2022.07.04
* 修改日期:2022.07.04
*
* Copyright (c) 2022 HanKin. All rights reserved.
*/
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#define MAX_BUF_LEN 64
int main()
{
do {
sleep(5);
FILE *fp = fopen("/home/study_service", "a");
// 记录当前时间(外设插拔) 获取日期(文件夹)
char cur_time[MAX_BUF_LEN] = {0}, cur_date[MAX_BUF_LEN] = {0};
time_t tm = time(NULL);
strftime(cur_time, sizeof(cur_time), "%Y/%m/%d %H:%M:%S", localtime(&tm));
strftime(cur_date, sizeof(cur_date), "%Y%m%d/", localtime(&tm));
fprintf(fp, "%s\n", cur_time);
fclose(fp);
fp = NULL;
} while (false);
return 0;
}
3-3、执行结果
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #service study_service status
● study_service.service - study_service
Loaded: loaded (/lib/systemd/system/study_service.service; disabled; vendor preset: enabled)
Active: active (running) since 一 2022-07-04 19:41:04 CST; 4s ago
Main PID: 5966 (a.out)
CGroup: /system.slice/study_service.service
└─5966 /media/hankin/vdb/TransferStation/a.out
7月 04 19:41:04 ubuntu0006 systemd[1]: Started study_service.
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #service study_service status
● study_service.service - study_service
Loaded: loaded (/lib/systemd/system/study_service.service; disabled; vendor preset: enabled)
Active: activating (auto-restart) since 一 2022-07-04 19:40:59 CST; 4s ago
Process: 5044 ExecStart=/media/hankin/vdb/TransferStation/a.out (code=exited, status=0/SUCCESS)
Main PID: 5044 (code=exited, status=0/SUCCESS)
[root@ubuntu0006:/home] #tailf study_service
2022/07/04 19:50:33
2022/07/04 19:50:43
2022/07/04 19:50:53
2022/07/04 19:51:04
程序运行后,会出现运行5秒中后程序结束,服务5秒后重启程序,从而出现10秒打印一次。
将程序修改成无限执行后,服务认为程序没有挂掉就只做监听的作用,不再进行拉起程序操作。
不明白项目中为啥会无限执行拉起程序操作。。。。 服务修改成后台运行,即添加&符号,结果一样。
4、进一步探索(验证参数是否传入进去)
发现原来是daemon函数的问题,它是由fork函数创建子进程,父进程正常退出了。 代码见:D:\Github\Storage\linux\service\study_service.cpp
就会出现不断的拉起新的程序进行执行。
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #ps -ef | grep a.out
root 19444 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 19915 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 20359 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 20776 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 21204 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 21424 3190 0 22:11 pts/3 00:00:00 grep --color=auto a.out
root 21614 1 0 21:57 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 22012 1 0 21:58 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 22487 1 0 21:58 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
root 22896 1 0 21:58 ? 00:00:00 /media/hankin/vdb/TransferStation/a.out -D
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #killall -9 a.out
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #ps -ef | grep a.out
root 22197 3190 0 22:11 pts/3 00:00:00 grep --color=auto a.out
因此,是否可以这样认为,当我把程序改成了一个服务进行守护,是不是不再需要进行调用daemon函数,让其变成一个守护进程。
4-1、聊一聊&和daemon的区别
&跟当前的终端有关,没有进行创建子进程操作。 daemon是通过创建子进程来操作的。
5、linux系统启动之后执行某个命令
需求:Linux系统启动之后执行xset r rate 666 22命令 linux中使用服务来完成这一需求。
例如:cat /lib/systemd/system/networking.service
[Unit]
Description=Raise network interfaces
Documentation=man:interfaces(5)
DefaultDependencies=no
Wants=network.target
After=local-fs.target network-pre.target apparmor.service systemd-sysctl.service systemd-modules-load.service
Before=network.target shutdown.target network-online.target
Conflicts=shutdown.target
[Install]
WantedBy=multi-user.target
WantedBy=network-online.target
[Service]
Type=oneshot
EnvironmentFile=-/etc/default/networking
ExecStartPre=-/bin/sh -c '[ "$CONFIGURE_INTERFACES" != "no" ] && [ -n "$(ifquery --read-environment --list --exclude=lo)" ] && udevadm settle'
ExecStart=/sbin/ifup -a --read-environment
ExecStop=/sbin/ifdown -a --read-environment --exclude=lo
RemainAfterExit=true
TimeoutStartSec=5min
6、验证自定义的服务启动顺序和弱依赖是否有受影响
After=network-online.target
Wants=network-online.target
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #systemctl status network-online.target
● network-online.target - Network is Online
Loaded: loaded (/lib/systemd/system/network-online.target; static; vendor preset: enabled)
Active: inactive (dead) since 三 2022-07-06 14:29:16 CST; 15s ago
Docs: man:systemd.special(7)
http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
7月 06 14:27:55 ubuntu0006 systemd[1]: Reached target Network is Online.
7月 06 14:29:16 ubuntu0006 systemd[1]: Stopped target Network is Online.
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #systemctl start study_service
[root@ubuntu0006:/media/hankin/vdb/TransferStation] #systemctl status network-online.target
● network-online.target - Network is Online
Loaded: loaded (/lib/systemd/system/network-online.target; static; vendor preset: enabled)
Active: active since 三 2022-07-06 14:29:39 CST; 2s ago
Docs: man:systemd.special(7)
http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
7月 06 14:29:39 ubuntu0006 systemd[1]: Reached target Network is Online.
通过实战发现,Wants弱依赖指的是会把依赖的服务启动起来,但是依赖的服务停止不影响当前服务。 去掉Wants后,当前服务不受After的启动顺序,当前服务能启动起来。
因此,这两个选项不是必须的。