当前位置: 首页 > news >正文

实测记录:测试开机启动脚本在CentOS上的表现

实测记录:测试开机启动脚本在CentOS上的表现

你有没有遇到过这样的问题:写好了一个监控脚本、日志清理工具,或者服务健康检查程序,每次重启服务器后都得手动运行一次?既麻烦又容易遗漏,还可能影响业务连续性。其实,Linux系统早就提供了成熟的机制来解决这个问题——通过系统级的开机自启动脚本,让关键任务在系统就绪后自动运行。

本文不是泛泛而谈的概念介绍,而是基于真实环境的一次完整实测记录。我们使用的是标准CentOS系统(具体为CentOS 7),全程不依赖systemd服务单元文件(避免混淆传统SysV init与现代systemd的区别),专注验证最经典、最兼容、也最容易被新手理解的/etc/init.d+rc*.d软链接方式。所有步骤均经过反复验证,每一步都有明确目的和可观察结果,确保你照着做就能成功。

整个过程不需要安装额外软件,不修改内核参数,不调整SELinux策略,只用系统自带命令完成。如果你正在维护一台老版本CentOS服务器,或者需要确保脚本在多种init风格下稳定运行,这篇实测记录就是为你准备的。


1. 明确目标与环境前提

在动手前,先理清我们要达成什么,以及系统当前处于什么状态。

1.1 本次实测的核心目标

  • 验证一个自定义Shell脚本能否在CentOS系统启动完成后自动执行
  • 确认脚本执行时机是否合理(即:网络已就绪、磁盘已挂载、基础服务已启动)
  • 排查常见失败原因:权限问题、路径错误、依赖未就绪、启动顺序不当
  • 提供可复用的最小可行模板,而非复杂配置

注意:本文聚焦SysV init风格的传统启动流程,适用于CentOS 6及CentOS 7(即使默认使用systemd,仍完全兼容/etc/init.d脚本调用)。不涉及systemctl enable.service文件写法,避免概念交叉干扰。

1.2 当前系统环境确认

我们先快速确认几个关键信息,避免后续操作踩坑:

# 查看系统版本(确认是CentOS) cat /etc/redhat-release # 输出示例:CentOS Linux release 7.9.2009 (Core) # 查看默认运行级别(CentOS 7中,systemd使用target替代runlevel,但兼容runlevel命令) runlevel # 输出示例:N 3 → 表示当前运行级别为3(多用户文本模式) # 查看默认启动target(补充验证) systemctl get-default # 输出示例:multi-user.target

这里特别说明:虽然CentOS 7默认使用systemd,但它完全保留并兼容SysV init机制/etc/rc.d/rc脚本会按需加载/etc/rc3.d/(对应multi-user.target)或/etc/rc5.d/(对应graphical.target)中的链接。因此,我们仍可沿用熟悉的rc*.d目录逻辑,无需切换思维模式。


2. 编写一个可验证的测试脚本

脚本不能只是“能跑”,更要“可追踪”——我们需要清楚知道它是否真的被执行、何时执行、执行结果如何。

2.1 创建脚本文件/etc/init.d/mytest.sh

直接在终端中执行以下命令创建脚本(注意:必须保存在/etc/init.d/目录下,且有执行权限):

sudo tee /etc/init.d/mytest.sh << 'EOF' #!/bin/bash # # mytest A simple test script for boot startup # chkconfig: 35 99 01 # description: Test script to verify boot execution timing and behavior # processname: mytest # Source function library . /etc/rc.d/init.d/functions start() { echo -n "Starting mytest: " # 记录启动时间、主机名、IP地址到日志 echo "[$(date '+%Y-%m-%d %H:%M:%S')] STARTED on $(hostname) at $(ip -4 addr show eth0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)" >> /var/log/mytest.log # 模拟一个轻量级操作:创建标记文件 touch /tmp/mytest_started success echo } stop() { echo -n "Stopping mytest: " echo "[$(date '+%Y-%m-%d %H:%M:%S')] STOPPED" >> /var/log/mytest.log rm -f /tmp/mytest_started success echo } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) if [ -f /tmp/mytest_started ]; then echo "mytest is running." else echo "mytest is stopped." fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 EOF # 设置执行权限 sudo chmod +x /etc/init.d/mytest.sh

这个脚本做了几件关键的事:

  • 使用标准SysV init函数库(/etc/rc.d/init.d/functions),保证输出格式统一、支持success/failure提示
  • chkconfig行声明了它适用于运行级别3和5,启动序号99(最后启动),关闭序号01(最早停止)
  • 启动时记录精确时间、主机名和主网卡IP到/var/log/mytest.log,并创建/tmp/mytest_started作为运行标记
  • 支持start/stop/restart/status四类操作,方便手动调试

2.2 手动运行一次,验证脚本本身无误

sudo /etc/init.d/mytest.sh start sudo /etc/init.d/mytest.sh status # 应输出:mytest is running. # 查看日志是否写入 sudo tail -n 1 /var/log/mytest.log # 应看到类似:[2024-06-15 14:22:33] STARTED on centos7-test at 192.168.1.100 # 清理测试痕迹 sudo /etc/init.d/mytest.sh stop

只有这一步成功,才能进入下一步。否则所有开机启动都是空谈。


3. 将脚本注册为系统服务

CentOS不会自动扫描/etc/init.d/下的所有脚本。我们必须显式告诉系统:“这个脚本需要在启动时运行”。

3.1 使用chkconfig命令注册(推荐方式)

chkconfig是CentOS管理SysV服务的官方工具,比手动建软链接更安全、更可维护:

# 将脚本添加到服务列表 sudo chkconfig --add mytest.sh # 设置在运行级别3和5下开机自启 sudo chkconfig mytest.sh on # 验证是否注册成功 sudo chkconfig --list mytest.sh # 输出应包含:mytest.sh 0:off 1:off 2:off 3:on 4:off 5:on 6:off

为什么推荐chkconfig而不是手动ln -s

  • 它会自动在/etc/rc3.d//etc/rc5.d/下创建正确的S99mytest.shK01mytest.sh链接
  • 自动处理符号链接命名规范(S开头+两位数字+脚本名)
  • 支持chkconfig --del一键卸载,避免残留链接
  • 兼容性更好,尤其在混合systemd/SysV环境中

3.2 (备选)手动创建软链接(仅作原理理解)

如果你希望彻底理解底层机制,可以跳过chkconfig,手动操作:

# 进入对应运行级别的rc目录(以3为例) cd /etc/rc3.d/ # 创建启动链接:S99mytest.sh(99表示最后启动) sudo ln -s /etc/init.d/mytest.sh S99mytest.sh # 创建停止链接:K01mytest.sh(01表示最早停止) sudo ln -s /etc/init.d/mytest.sh K01mytest.sh # 验证链接存在且指向正确 ls -l S99mytest.sh # 应输出:S99mytest.sh -> /etc/init.d/mytest.sh

注意:手动创建时,务必确保链接名符合SxxNameKxxName格式,否则rc脚本不会识别。


4. 验证启动时机与执行效果

光注册还不够,我们必须确认它真的在正确的时间点执行了,并且执行结果符合预期

4.1 检查启动链接是否生效

# 查看rc3.d目录下是否有我们的链接 ls -l /etc/rc3.d/S99* # 查看脚本是否被chkconfig识别 sudo chkconfig --list | grep mytest

4.2 模拟一次“伪重启”进行快速验证(不真正重启)

频繁重启服务器既耗时又影响其他服务。我们可以用systemctl触发一次rc-local式的手动启动,模拟开机流程:

# 在CentOS 7中,/etc/rc.d/rc3.d/下的S*脚本由/etc/rc.d/rc脚本统一调用 # 我们可以直接运行rc脚本(指定运行级别3) sudo /etc/rc.d/rc 3

此命令会按顺序执行/etc/rc3.d/S*下所有脚本。请确保你了解其影响(它会启动所有S*服务,包括网络、sshd等)。如不确定,建议直接重启测试。

4.3 最终验证:重启系统并检查结果

# 执行重启(生产环境请谨慎!) sudo reboot

等待系统完全启动后,登录并立即检查:

# 检查标记文件是否存在 ls -l /tmp/mytest_started # 应存在,且时间戳接近系统启动时间 # 查看日志内容 sudo cat /var/log/mytest.log # 应看到类似: # [2024-06-15 14:30:22] STARTED on centos7-test at 192.168.1.100 # 检查网络是否已就绪(验证执行时机) ip addr show eth0 | grep 'inet ' # 应能正常显示IP,证明脚本是在网络服务启动后执行的 # 检查脚本状态 sudo /etc/init.d/mytest.sh status # 应输出:mytest is running.

如果以上全部满足,恭喜你——开机启动脚本已成功落地。


5. 常见问题与排查指南

实测过程中,90%的问题都出在几个固定环节。以下是高频故障点及对应解法:

5.1 脚本根本没执行?

  • 检查点1:脚本权限
    ls -l /etc/init.d/mytest.sh→ 必须有x执行权限(-rwxr-xr-x

  • 检查点2:脚本首行shebang
    必须是#!/bin/bash#!/bin/sh,不能是Windows换行符(^M),可用dos2unix /etc/init.d/mytest.sh修复

  • 检查点3:chkconfig元数据缺失
    脚本头部必须包含# chkconfig:行,否则chkconfig --add会失败

5.2 脚本执行了,但功能异常(如无法访问网络、找不到命令)?

  • 原因:执行环境过于精简
    开机脚本运行时,PATH变量极短(通常只有/sbin:/usr/sbin:/bin:/usr/bin),很多常用命令(如jqcurlpython3)不在其中。

  • 解法:在脚本中显式声明PATH

    # 在脚本开头添加 export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
  • 解法:使用绝对路径调用命令

    # 不要写 curl -s http://api.example.com/health # 要写 /usr/bin/curl -s http://api.example.com/health

5.3 日志为空,或时间戳异常?

  • 原因:脚本在系统日志服务(rsyslog)启动前就运行了
    导致>> /var/log/mytest.log重定向失败(目录不存在或无权限)

  • 解法:添加延迟或依赖检查

    # 在start()函数中加入等待 while [ ! -f /var/log/messages ]; do sleep 1 done
  • 更优解:使用logger命令写入系统日志

    logger "mytest: service started successfully" # 日志将出现在 /var/log/messages 中,且时机更可靠

6. 总结:一条可复用的开机启动实践路径

回顾整个实测过程,我们走通了一条从零开始、稳扎稳打的开机脚本落地路径。它不依赖任何第三方工具,不修改系统核心配置,完全基于CentOS原生机制,具备强兼容性和可维护性。

6.1 关键结论

  • SysV init机制在CentOS 7中依然健壮有效chkconfig是注册服务的首选工具
  • 脚本执行时机取决于运行级别rc3.d对应文本模式,rc5.d对应图形界面;选择哪个取决于你的服务器用途
  • 启动序号(如99)决定执行顺序:数值越大越晚执行,适合依赖数据库、网络等后置服务的脚本
  • 日志是排错的第一依据:务必在脚本中记录时间、环境、关键状态,避免“黑盒”执行

6.2 下一步建议

  • 将此模板扩展为实际业务脚本:例如定时清理/tmp、监控磁盘使用率、上报服务器心跳
  • 结合cron实现“启动后延时执行”(如@reboot sleep 60 && /path/to/script.sh),应对需要更晚时机的场景
  • 对于新项目,可逐步迁移到systemd服务单元,但本方案仍是维护旧系统的黄金标准

你不需要记住所有命令,只需要记住这个最小闭环:
写脚本 → 加权限 → 写chkconfig头 → chkconfig --add → chkconfig on → reboot验证
剩下的,就是把它用在真正需要的地方。


获取更多AI镜像

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

http://www.cnnetsun.cn/news/853106.html

相关文章:

  • 图片分析不求人:mPLUG视觉问答工具保姆级使用指南
  • Qwen-Image-Edit-F2P应用场景:社交媒体配图一键生成攻略
  • 为什么我推荐你用SenseVoiceSmall而不是Whisper?
  • DeepChat开源模型部署:Llama3:8b在Ollama中量化(Q4_K_M)与性能平衡实操分享
  • MedGemma X-Ray企业应用:三甲医院教学查房AI实时影像解读演示系统
  • 终于找到好用的中文生图工具!Z-Image-ComfyUI实测
  • 24G显卡也能用!FLUX.1-dev稳定运行秘诀大公开
  • DeepAnalyze部署教程:Kubernetes集群中DeepAnalyze镜像的资源请求与限制配置
  • Clawdbot+Qwen3:32B多场景落地:制造业BOM解析、物流单据识别与生成
  • YOLOE官版镜像效果展示:YOLOE统一架构下检测框与分割mask同步输出
  • Chandra代码实例:通过curl/API调用Chandra后端服务的Python示例
  • 手把手教你部署Open-AutoGLM模型服务(本地+云端)
  • MedGemma-X实战案例:AI辅助生成放射科继续教育学习要点总结
  • nlp_gte_sentence-embedding_chinese-large效果展示:中文技术文档术语一致性检测
  • Qwen3-32B开源可部署方案:Clawdbot镜像+Web UI+API服务三位一体教程
  • 保姆级GTE教程:手把手教你搭建中文问答系统
  • 交叉编译原理与流程:图解说明核心要点
  • Clawdbot+Qwen3-32B部署教程:支持LLM输出Token计费与用量统计功能
  • MATLAB的智能扫地机器人工作过程仿真
  • Flowise场景实现:保险理赔咨询自动化响应系统
  • Qwen3-Reranker-0.6B详细步骤:API响应延迟监控与性能压测方法
  • EagleEye动态过滤展示:同一张图不同灵敏度设置下的漏检/误报平衡演示
  • StructBERT语义匹配系统应用场景:HR简历关键词匹配落地解析
  • Local AI MusicGen质量评估:WAV保真度、频谱连续性、人耳主观评分报告
  • GLM-4-9B-Chat-1M部署案例:始智AI平台GPU集群调度+模型服务化封装
  • 阿里GPEN实战:手把手教你拯救AI生成的脸崩图片
  • 中小企业如何部署Qwen2.5?低成本GPU方案实战
  • 看完就想试!科哥打造的语音情绪识别系统效果太直观了
  • Chandra OCR体验:数学试卷秒变Markdown笔记
  • 一键部署WeKnora:让AI成为你的私人知识管家(附实战案例)