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

测试开机启动脚本

测试开机启动脚本

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

你有没有遇到过这样的问题:写好了开机启动脚本,却不知道它到底在哪个阶段被加载?改完 /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星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

您可能感兴趣的与本文相关的镜像

测试开机启动脚本

测试开机启动脚本

PyTorch

测试开机启动脚本

【重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值