Linux设置开机自启程序
$Background$
SysVinit和Systemd
早期/嵌入式Linux系统是以 init 作为系统启动后第一个运行的用户空间进程(其进程 ID 通常为 1),它被内核直接启动,负责初始化系统并启动其他进程和服务。该种模式叫做SysVinit或SysV。
而在现代 Linux 中(如 Ubuntu 16.04+、CentOS 7+、Fedora 等),SysVinit 已被 Systemd 取代。
虽然现代 Linux 还存在 init 程序,但该程序仅是 systemd 程序的符号链接/sbin/init -> /lib/systemd/systemd,而systemd 是通过终端命令 systemctl 来操作管理的。
inittab是位于/etc/inittab的配置文件,定义init进程的行为,如
si::sysinit:/etc/init.d/rcS系统初始化脚本。1:2345:respawn:/sbin/getty 38400 tty1在指定运行级别下启动虚拟终端,并如果进程退出则重启。在现代 Linux 中 systemd 使用单元文件(.service、.target 等)来管理这些功能,因此
inittab文件通常不存在
二者的区别
SysVinit 根据符号链接名逐一执行对应脚本,即串行执行
- 如果某个服务启动缓慢,整个启动过程都会被阻塞。
- 依赖关系是通过脚本中的注释来声明的,但
SysVinit本身并不强制执行这些依赖。 - 通常需要手动编写复杂的 Shell 脚本来处理启动、停止等任务。
Systemd 将系统启动和服务管理看作是一个事件驱动和并行处理的过程
- 可以同时启动多个不相互依赖的服务
- 能跟踪服务的整个生命周期,包括其主进程、子进程、日志和资源使用情况
- 服务可以按需启动
$Method$
分为现代Linux和早期Linux两种情况下实现开机自启脚本
现代Linux
现代Linux使用 systemctl 命令操作 systemd 进程管理设置开机自启脚本
systemd管理多种类型的程序,不同类型应用的场景不同,如
- Service类型,定义服务程序的启动、停止、重启等操作和进程相关属性
- Target类型,对Service或其它Unit进行分组、归类,可以包含一个或多个Unit
Unit(单元)是 Systemd 管理和操作的基本单位,它是一个配置文件,描述 Systemd 应该如何处理一个资源
.service file
设置服务文件内容,文件路径 /etc/systemd/system/
sudo vim /etc/systemd/system/xxx-yyy-zzz.service
Note: 服务文件名称不能带数字,最好是
xxx-yyy-zzz.service
.service 文件内容字段解释
[Unit]
Description=some descriptions
Requires=xxx1.target xxx2.target
After=yyy1.target yyy2.target
[Service]
Type=<TYPE>
ExecStart=<CMD_for_START>
ExecStop=<CMD_for_STOP>
ExecReload=<CMD_for_RELOAD>
Restart=<WHEN_TO_RESTART>
RestartSec=<TIME>
[Install]
WantedBy=xxx.target yy.target
Unit:定义该服务的服务描述、启动顺序和依赖关系。Service:定义该服务的启动行为,如何启动、重启、停止。Install:定义该服务在设置服务开机自启动时相关的属性。
只有在创建/移除服务配置文件的软链接时,Install段才会派上用场。这一配置段不是必须的,当未配置
[Install]时,设置开机自启动或禁止开机自启动的操作将无任何效果
Unit部分常用字段
Description,Unit的描述信息After/Before,定义启动顺序,不定义服务依赖关系,即使要求先启动的服务启动失败,本服务也会启动Wants/Requires,定义服务依赖关系,不定义服务启动顺序
启动顺序或者服务依赖关系都是通过指定
xxx.target方式实现
Service常用字段
Type=simple/forking/oneshot:指定服务的管理类型,启动即运行/启动后派生子进程/仅执行一次ExecStart:指定启动服务时执行的命令行ExecStop:指定停止服务时执行的命令行ExecReload:指定重载服务进程时执行的命令行Restart=no/always/on-failure/on-abnormal:指定systemd是否要自动重启服务进程以及什么情况下重启WorkingDirectory:指定命令执行的工作目录User:指定以哪个用户的身份运行命令行
所要执行的命令行需要指定绝对路径,如
bash写作/bin/bash
Install部分常用字段
WantedBy/RequiredBy,设置开机自启动时,在被依赖目标的.wants/.requires目录下创建本服务的软链接
例子
[Unit]
Description=My Project
After=network.target
[Service]
WorkingDirectory=/home/pi
ExecStart=/usr/bin/python3 my_script.py
User=pi
Restart=always
[Install]
WantedBy=multi-user.target
应用配置文件
配置完成后,设置该服务开机自启+立即启动
sudo systemctl daemon-reload
sudo systemctl enable xxx-yyy-zzz.service
sudo systemctl start xxx-yyy-zzz.service
systemctl daemon-reload,重新加载 Systemd 配置systemctl enable xxx.serivce,启用服务,使其在开机时自动启动systemctl start xxx.service,立即启动服务
查看当前服务状态
sudo systemctl status xxx-yyy-zzz.service
查看运行该服务的日志
journalctl -u xxx-yyy-zzz.service -n 50 --no-pager
.target
multi-user.target,代表一个完整的多用户命令行系统。这是大多数 Linux 服务器和树莓派在启动时通常会进入的默认状态。它会启用所有核心服务,如网络、日志和串行接口,但不包括图形界面。graphical.target,代表一个完整的图形用户界面系统。它包含了multi-user.target中的所有服务,并额外启动了图形界面相关的所有服务。network.target,代表网络设备(如以太网卡)已配置完成。network-online.target,代表网络已完全连接并可用。这意味着不仅网卡已配置,而且 IP 地址也已分配,可以正常访问互联网。local-fs.target,代表所有本地文件系统已挂载完毕。basic.target,代表 Systemd 启动的早期阶段,仅包含最基本的系统服务。
早期/嵌入式Linux
早期/嵌入式Linux在/etc/init.d/文件夹中设置开机自启程序
/etc/init.d/下面有两个bash脚本 rcS和rcK
S代表开始Start,即系统开机后执行的bash脚本K代表中止Kill,即系统关机后执行的bash脚本
执行的文件以文件名命名的方式决定执行顺序,即S后面的数字表示启动的顺序,数字小的先启动
要实现开机自启则直接在 rcS 中增加一个总的执行脚本路径,之后再在该脚本中写入真正需要执行的程序/脚本
使用
/bin/sh启动脚本,这样不管这个脚本有没有可执行权限,都会执行使用后台运行“&”,这样不影响父程序脚本的正常执行
runlevel
runlevel运行级别N
- 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
- 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
- 运行级别2:多用户状态(没有NFS)
- 运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
- 运行级别4:系统未使用,保留
- 运行级别5:X11控制台,登陆后进入图形GUI模式
- 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动
runlevel是SysV初始化系统中的概念,在Systemd初始化系统中使用的是 Target,常见target与其之间的映射关系是
| Runlevel | Target | 说明 |
|---|---|---|
| 0 | poweroff.target | 关闭系统 |
| 1 | rescue.target | 维护模式 |
| 2,3,4 | multi-user.target | 多用户,无图形系统(命令行界面) |
| 5 | graphical.target | 多用户,图形化系统(图形用户界面) |
| 6 | reboot.target | 重启系统 |
$Reference$
https://cloud.tencent.com/developer/article/2441165
https://www.junmajinlong.com/linux/systemd/service_1/
https://www.cnblogs.com/usmile/p/13065594.html
https://blog.csdn.net/a913909626/article/details/118405378