系统运行级别怎么看?配合测试脚本轻松理解
2026/4/14 21:52:12 网站建设 项目流程

系统运行级别怎么看?配合测试脚本轻松理解

你有没有遇到过这样的问题:写好了开机启动脚本,却不知道它到底在哪个阶段被加载?改完/etc/init.d/mytest.sh,重启后发现脚本压根没执行——不是代码错了,而是根本没被系统“看见”。其实,背后的关键就是系统运行级别(Runlevel)。它像一张启动时刻的“时间表”,决定了哪些服务该在什么时候启动、哪些该停止。本文不讲抽象概念,不堆术语,就用一个真实可运行的测试脚本,带你一步步看清:你的系统当前在哪个级别运行?这个级别对应哪些启动目录?脚本要放在哪里、怎么命名、按什么顺序执行,才能真正生效。

整个过程在 CentOS 和 Ubuntu 系统上都适用,不需要安装额外软件,所有命令都是系统自带。哪怕你刚接触 Linux 不久,只要能敲几行命令、看懂文件名含义,就能彻底搞明白开机启动背后的逻辑。

1. 先写一个看得见效果的测试脚本

与其对着空脚本猜来猜去,不如先写一个“会说话”的脚本——它每次执行时,都会在系统日志里留下明确痕迹,让你一眼确认:它真的运行了。

我们把它放在标准位置/etc/init.d/mytest.sh

#!/bin/bash ### BEGIN INIT INFO # Provides: mytest # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Test startup script # Description: A simple script to log boot time execution ### END INIT INFO case "$1" in start) echo "$(date): mytest.sh started successfully" >> /var/log/mytest.log ;; stop) echo "$(date): mytest.sh stopped" >> /var/log/mytest.log ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0

这段脚本非常轻量,只做一件事:当被要求start时,往/var/log/mytest.log文件里写一行带时间戳的日志。它不依赖数据库、不调用网络服务,纯粹用来验证“启动流程是否走通”。

保存后,给它执行权限:

sudo chmod +x /etc/init.d/mytest.sh

现在,脚本已就位,但它还不会自动运行——因为系统还不知道该在什么时候、以什么方式调用它。接下来,我们就从最基础的问题开始:我的系统现在处于哪个运行级别?

2. 查看当前系统运行级别:runlevel 命令一目了然

Linux 系统启动后,并不是直接进入图形界面或命令行,而是先进入一个预定义的“运行状态”,这就是运行级别(Runlevel)。不同级别代表不同的服务组合:比如级别 3 是多用户命令行模式,级别 5 是带图形界面的完整桌面环境。

查看当前运行级别,只需一条命令:

runlevel

执行后,你会看到类似这样的输出:

N 5

这表示:上一个运行级别是 N(None,即系统刚启动,无前级),当前运行级别是 5

关键点:数字 5 意味着系统启动时,会自动加载/etc/rc5.d/目录下的所有启动脚本。换句话说,如果你希望脚本在图形界面启动完成后才运行,就必须确保它出现在/etc/rc5.d/中;如果只想在纯命令行下运行,则应关注/etc/rc3.d/

那这些rc*.d目录和/etc/init.d/是什么关系?一句话说清:

  • /etc/init.d/所有服务脚本的“源仓库”,你写的mytest.sh就放在这里;
  • /etc/rc5.d/(或其他 rc*.d)是运行级别 5 的“执行清单”,里面没有真实脚本,只有一堆指向/etc/init.d/脚本的软链接。

它们之间不是复制关系,而是“调度关系”——系统启动时,只读取rc5.d/下的链接,再根据链接去执行init.d/里的真实脚本。

3. 进入对应 rc 目录:看清启动顺序的本质

既然runlevel显示当前是 5,那就直接进/etc/rc5.d/看看里面到底有什么:

cd /etc/rc5.d/ ls -l

你大概率会看到一堆以SK开头的文件,例如:

S10sysklogd S20rsyslog S50apache2 S99mytest K01network

这些名字不是随意起的,而是有严格含义的:

  • S开头:表示Start(启动),系统启动时执行;
  • K开头:表示Kill(停止),系统关机或切换级别时执行;
  • 紧随其后的两位数字(如 10、50、99):表示执行顺序,数字越小越早执行,越大越晚。

为什么顺序重要?举个实际例子:
你的脚本如果需要访问 MySQL 数据库,而 MySQL 服务本身是S20mysql,那你自己的脚本就不能叫S10mytest——否则它会在 MySQL 启动前就尝试连接,必然失败。合理的做法是命名为S99mytest,确保它排在绝大多数基础服务之后执行。

注意:Ubuntu 16.04 及以后版本默认使用 systemd,传统 SysV init 的 rc*.d 机制虽仍兼容,但优先级低于 systemd 单元。不过,对于快速验证、教学演示或遗留系统维护,这套机制依然清晰、可靠、无需额外学习成本。

4. 为脚本创建软链接:让系统“认出”它

现在,我们把/etc/init.d/mytest.sh正式加入到运行级别 5 的启动队列中。方法很简单:在/etc/rc5.d/下创建一个指向它的软链接。

执行这条命令:

sudo ln -s /etc/init.d/mytest.sh /etc/rc5.d/S99mytest

注意命名规则:

  • S99表示“启动”,序号99表示最后执行(稳妥起见,避免依赖冲突);
  • mytest是链接名,建议与脚本名保持一致,便于识别。

创建完成后,再次运行ls -l,你应该能看到:

S99mytest -> /etc/init.d/mytest.sh

这就完成了最关键的一步:系统启动时,会按顺序执行S99mytest,而它实际调用的就是你写的/etc/init.d/mytest.sh

小技巧:如果你希望脚本在多个运行级别都生效(比如 2、3、4、5),可以分别在/etc/rc2.d//etc/rc3.d/等目录下创建对应链接。但对大多数桌面或服务器场景,rc5.d已足够覆盖需求。

5. 验证效果:重启不是唯一方式,更安全的测试法

很多教程直接说“reboot 测试”,但频繁重启既耗时又影响工作。其实,我们完全可以在不重启的前提下,手动触发一次“启动流程”,立即验证脚本是否有效。

执行以下命令,模拟系统在运行级别 5 下启动该服务:

sudo /etc/init.d/mytest.sh start

然后检查日志:

cat /var/log/mytest.log

你应该看到类似这样的一行:

Wed Oct 18 14:22:37 CST 2023: mytest.sh started successfully

说明脚本本身功能正常,权限正确,路径无误。

接下来,才是真正的“启动级验证”:
我们不重启整机,而是临时切换一次运行级别,让系统真正走一遍rc5.d的加载流程:

# 切换到运行级别 3(命令行模式) sudo telinit 3 # 再切回 5(图形界面模式) sudo telinit 5

注意:telinit在部分新版 Ubuntu 上可能被systemctl替代,若提示命令未找到,可改用sudo systemctl isolate multi-user.target(对应级别 3)和sudo systemctl isolate graphical.target(对应级别 5)。但原理完全一致:强制系统重新加载对应目标级别的所有服务。

切换完成后,再次查看日志:

tail -n 1 /var/log/mytest.log

如果出现新的时间戳记录,恭喜你——你的脚本已经成功嵌入系统启动流程,不再是“写好了却没人管”的孤本。

6. 常见问题与实用建议:避开新手最容易踩的坑

即使步骤全对,也常因几个细节导致失败。以下是真实环境中高频出现的问题及解决思路:

问题一:脚本写了,链接也建了,但日志始终为空

排查重点

  • 检查脚本第一行#!/bin/bash是否存在且正确(不能是 Windows 换行符);
  • 确认/var/log/mytest.log所在目录/var/log/是否可写(ls -ld /var/log);
  • 运行sudo /etc/init.d/mytest.sh start手动测试,看是否报错(如权限拒绝、路径不存在)。

问题二:runlevel显示N 3,但我想在图形界面下运行

说明:这通常表示你当前处于纯命令行终端(如 Ctrl+Alt+F2),而非图形界面。可执行ps aux | grep lightdmps aux | grep gdm3查看图形管理器是否在运行。若未运行,可手动启动:sudo systemctl start gdm3(Ubuntu)或sudo systemctl start lightdm

问题三:Ubuntu 20.04+ 上rc5.d似乎没被调用

原因:新版本默认启用 systemd,SysV 兼容层仍在,但优先级较低。此时更推荐将脚本转为 systemd 服务单元(.service文件),但如果你只是想快速验证逻辑,rc5.d方式依然有效——只需确保systemd-sysv-generator已启用(默认开启),它会自动将rc*.d链接映射为 systemd 服务。

实用建议:

  • 命名统一:脚本名、链接名、日志名尽量保持一致(如mytest),避免混淆;
  • 日志轮转:长期使用建议添加 logrotate 配置,防止/var/log/mytest.log无限增长;
  • 退出码检查:脚本末尾exit 0很关键,非零退出码会被系统视为启动失败,可能导致后续服务跳过;
  • 依赖声明:脚本头部的Required-Start注释虽不影响 SysV 执行,但在转换为 systemd 时可自动生成依赖关系,建议保留。

7. 总结:运行级别不是黑盒,而是可观察、可控制的启动地图

到这里,你应该已经清楚:

  • runlevel命令不是摆设,它是打开启动机制的第一把钥匙;
  • rc5.d目录不是杂乱的文件夹,而是一张精确到秒级的“服务执行时间表”;
  • 软链接不是技术噱头,而是系统识别脚本身份的唯一凭证;
  • 日志验证比盲目重启更高效、更可控。

理解运行级别,本质上是在理解 Linux 启动的分阶段治理思想:不是所有服务一股脑全开,而是按依赖、按角色、按时机有序加载。这种设计让系统既稳定又灵活——你可以随时调整某个脚本的启动顺序,而不影响整体结构。

下一步,你可以尝试:

  • S99mytest改成S10mytest,观察它是否真的更早执行;
  • /etc/rc0.d/(关机级别)下创建K01mytest,让它在关机前写一行日志;
  • 对比 CentOS 7 和 Ubuntu 22.04 的runlevel输出差异,思考 init 系统演进的底层逻辑。

知识只有在动手验证后,才真正属于自己。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询