M3ngL

Linux设置开机自启程序

$Background$

SysVinit和Systemd

早期/嵌入式Linux系统是以 init 作为系统启动后第一个运行的用户空间进程(其进程 ID 通常为 1),它被内核直接启动,负责初始化系统并启动其他进程和服务。该种模式叫做SysVinitSysV

而在现代 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脚本 rcSrcK

  • 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

📑
目录