news 2026/3/8 8:40:06

一个小脚本解决大问题,这才是运维利器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个小脚本解决大问题,这才是运维利器

一个小脚本解决大问题,这才是运维利器

你有没有遇到过这样的场景:服务器重启后,某个关键服务没起来,业务直接中断;或者每次手动启动一堆监控脚本、日志清理任务,重复操作又累又容易出错?其实,一个不到20行的开机启动脚本,就能把这些问题一劳永逸地解决掉。它不依赖复杂工具,不增加系统负担,却能稳稳托住你的线上服务——这才是真正接地气、可落地、见效快的运维利器。

这篇文章不讲高深理论,也不堆砌术语。我们就用最朴实的方式,带你从零写出一个可靠的开机自启脚本,并在CentOS和Ubuntu上都验证通过。无论你是刚接触Linux的新手,还是每天和服务器打交道的老运维,都能照着做、马上用、不出错。

1. 先搞懂一件事:开机启动不是“随便放个脚本就行”

很多人以为,只要把脚本丢进某个目录,系统就会自动运行它。但现实是:Linux启动过程有明确的阶段划分,脚本必须放在对的位置、起对的名字、满足基本规范,才能被正确识别和执行。

核心就两点:

  • 脚本得放在/etc/init.d/目录下(这是传统SysV init系统的标准位置,CentOS 6/7 和 Ubuntu 16.04+ 的兼容模式都支持)
  • 脚本本身要带基础控制逻辑:至少能响应startstopstatus这三个命令,否则系统无法管理它

别担心,这个要求一点都不难。下面我们就写一个真正可用的mytest.sh,它会做一件简单但很典型的事:开机时自动创建一个标记文件,并记录启动时间。

1.1 写一个“能说话”的启动脚本

打开终端,用你喜欢的编辑器(比如nanovim),创建/etc/init.d/mytest.sh

#!/bin/bash # chkconfig: 2345 99 01 # description: A simple test service for boot startup # processname: mytest # 定义服务名称和日志路径 SERVICE_NAME="mytest" LOG_FILE="/var/log/mytest.log" MARK_FILE="/tmp/mytest_booted" # 启动函数 start() { echo "Starting $SERVICE_NAME..." echo "Boot time: $(date)" > "$MARK_FILE" echo "$(date): Service started" >> "$LOG_FILE" touch /var/lock/subsys/$SERVICE_NAME } # 停止函数 stop() { echo "Stopping $SERVICE_NAME..." rm -f "$MARK_FILE" echo "$(date): Service stopped" >> "$LOG_FILE" rm -f /var/lock/subsys/$SERVICE_NAME } # 状态函数 status() { if [ -f /var/lock/subsys/$SERVICE_NAME ]; then echo "$SERVICE_NAME is running" else echo "$SERVICE_NAME is not running" fi } # 根据参数调用对应函数 case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac

为什么这个脚本能被系统识别?
第二行# chkconfig: 2345 99 01是关键——它告诉chkconfig工具:这个服务应该在运行级别2、3、4、5下启动,启动序号99(靠后),停止序号01(靠前)。虽然现代系统不一定用chkconfig,但保留它能提升兼容性。
第三行# description:是服务描述,方便后续查看。
最重要的是:它实现了start/stop/status三个标准动作,这是所有启动脚本的“身份证”。

1.2 设置权限并测试本地运行

脚本写完后,必须给它可执行权限:

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

现在就可以不重启,直接测试它是否工作正常:

# 手动启动 sudo /etc/init.d/mytest.sh start # 查看状态 sudo /etc/init.d/mytest.sh status # 检查标记文件和日志 cat /tmp/mytest_booted tail -n 1 /var/log/mytest.log

如果看到类似mytest is running和正确的日期输出,说明脚本本身完全没问题。这一步非常关键——永远先确保脚本本地能跑通,再谈开机启动

2. 系统怎么知道该什么时候运行它?运行级别和rc目录的秘密

Linux启动时,并不是一股脑儿把所有脚本全拉起来。它按“运行级别”(Runlevel)分阶段加载服务。你可以把它理解成“开机流程图”里的不同关卡:

  • Runlevel 0:关机
  • Runlevel 1:单用户模式(维护用)
  • Runlevel 2~5:多用户模式,其中3 和 5 是最常见的默认级别(3是纯命令行,5带图形界面)
  • Runlevel 6:重启

那系统怎么决定在哪个级别加载你的脚本?答案就在/etc/rcX.d/目录里。

2.1 查看当前系统的默认运行级别

运行这条命令:

runlevel

你会看到类似N 5的输出。前面的N表示“之前没有运行级别”,后面的5就是当前级别——也就是系统启动时默认进入的级别。

小贴士:CentOS 7+/Ubuntu 18.04+ 默认使用 systemd,但为了兼容老脚本,它们仍保留了 SysV init 的模拟层。runlevel命令依然有效,/etc/rc5.d/目录也真实存在。

2.2/etc/rc5.d/目录里到底有什么?

进入该目录看看:

cd /etc/rc5.d/ ls -l

你会发现一堆以SK开头的链接,比如S10networkS20sshdK99grub2。它们的命名规则非常清晰:

  • Sxx:Start,表示“启动服务”,xx是两位数字,代表执行顺序(01最早,99最晚)
  • Kxx:Kill,表示“停止服务”,同样按数字顺序执行
  • 所有这些链接,最终都指向/etc/init.d/下的真实脚本

所以,让我们的mytest.sh开机启动,本质就是:/etc/rc5.d/下创建一个指向它的Sxx链接

3. 创建软链接:三步搞定开机自启

这一步极简,但名字和顺序很重要。

3.1 为什么选S99mytest而不是S01mytest

因为S99表示“最后启动”。你的脚本很可能依赖网络、磁盘挂载、数据库等基础服务。如果它排在第一个(S01),而网络还没起来,脚本就会失败。S99是安全的选择——等绝大多数服务都就绪了,再轮到它。

当然,如果你的服务是基础设施级的(比如自定义的网络配置),可以适当调前,但99%的场景,S99最稳妥。

3.2 执行创建命令

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

注意:链接名是S99mytest,不是S99test。我们用服务名mytest,更清晰,避免歧义。

验证是否成功:

ls -l /etc/rc5.d/S99mytest

你应该看到类似这样的输出:

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

这就意味着:下次系统启动到 runlevel 5 时,它一定会执行/etc/init.d/mytest.sh start

4. 实战验证:不重启也能测效果

别急着reboot。我们可以用更安全、更快捷的方式模拟开机启动流程。

4.1 手动触发 rc5.d 的全部 S 脚本

sudo /etc/init.d/rc 5

这条命令会“假装”系统正切换到 runlevel 5,并依次执行/etc/rc5.d/下所有Sxx*脚本。你的S99mytest就在其中。

执行后,检查结果:

# 看服务是否被标记为运行中 sudo /etc/init.d/mytest.sh status # 看标记文件是否存在且内容正确 cat /tmp/mytest_booted # 看日志是否追加了新记录 tail -n 1 /var/log/mytest.log

如果一切正常,恭喜你——脚本已正式纳入系统启动流程,只等下次真正重启生效。

4.2 (可选)用 chkconfig 管理(CentOS 用户推荐)

如果你用的是 CentOS,还可以用更高级的工具统一管理:

# 添加服务到 chkconfig sudo chkconfig --add mytest # 设置开机自启(对所有多用户级别生效) sudo chkconfig mytest on # 查看状态 sudo chkconfig --list | grep mytest

它会自动为你在/etc/rc3.d//etc/rc5.d/下都创建S99mytest链接,省去手动操作。

5. 常见问题与避坑指南

写脚本容易,但让它长期稳定运行,需要避开几个经典陷阱。这些都是我在上百台服务器上踩过的坑,现在直接告诉你答案。

5.1 “脚本执行了,但什么都没发生?”——路径和环境变量问题

很多脚本里写了python3 /home/user/script.py,结果开机失败。原因很简单:/home分区可能还没挂载,或者PATH环境变量不包含/usr/local/bin

解决方案

  • 所有路径用绝对路径(/usr/bin/python3,不是python3
  • 在脚本开头显式设置 PATH:
    export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"

5.2 “日志里全是 Permission denied”——权限和用户问题

脚本默认以root身份运行,但如果它试图往普通用户目录写文件,就会失败。

解决方案

  • 日志、临时文件统一放在/var/log//tmp//var/run/这类 root 可写的系统目录
  • 如果必须操作用户数据,用sudo -u username command切换用户

5.3 “重启后发现脚本没运行”——检查锁文件和依赖

有时脚本启动逻辑里有判断,比如“如果锁文件存在就不重复执行”,但锁文件路径错了,或上次异常退出没清理干净。

解决方案

  • 启动前先清理旧锁:rm -f /var/lock/subsys/mytest
  • 加入简单防重逻辑(已在示例脚本中体现)
  • systemctl list-dependencies --reverse mytest.service(如转为 systemd)或检查/etc/rc5.d/链接是否真实存在

6. 进阶思考:这个小脚本能做什么大事情?

别小看这个“创建标记文件”的例子。它是一切自动化运维的起点。把里面的echo换成真实命令,它立刻就能承担重任:

  • 自动拉起 Docker 容器docker-compose -f /opt/app/docker-compose.yml up -d
  • 同步配置文件rsync -avz /etc/nginx/ user@backup-server:/backup/nginx/
  • 发送企业微信告警curl 'https://qyapi.weixin.qq.com/...' --data '{"msgtype":"text","text":{"content":"Server rebooted OK"}}'
  • 初始化数据库连接池mysql -u root -e "CREATE DATABASE IF NOT EXISTS app_db;"

关键是:它脱离了人工干预,成为系统自身的一部分。当故障发生、半夜告警、流量突增时,你不需要登录服务器,它已经默默完成了该做的事。

7. 总结:小脚本,大智慧

回看整个过程,我们只做了四件事:

  1. 写一个带start/stop/status的标准脚本
  2. 查清系统运行级别(通常是5)
  3. /etc/rc5.d/下创建S99mytest软链接
  4. /etc/init.d/rc 5快速验证,再reboot终极确认

没有安装新软件,没有修改内核,不依赖云平台,甚至不用联网。它纯粹依靠 Linux 最底层、最稳定的启动机制,却解决了运维中最高频、最琐碎、最容易出错的问题。

真正的运维利器,从来不是功能最炫的工具,而是最简单、最可靠、最经得起时间考验的那一行命令、一个脚本、一次配置。当你能把这种“小而确定”的能力,沉淀成团队的标准实践,你就已经走在了自动化运维的正确道路上。


获取更多AI镜像

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/7 6:07:22

Qwen3-1.7B科研应用场景:论文辅助写作系统搭建

Qwen3-1.7B科研应用场景:论文辅助写作系统搭建 1. 为什么选Qwen3-1.7B做科研写作助手? 做科研的人最常遇到的几个“卡点”你肯定不陌生:文献读到一半思路断掉、实验结果有了但不知道怎么组织成段落、引言写三遍还是像流水账、英文摘要改来改…

作者头像 李华
网站建设 2026/3/8 4:25:53

FSMN VAD高精度检测秘诀:参数调优与预处理实战手册

FSMN VAD高精度检测秘诀:参数调优与预处理实战手册 1. 为什么你需要真正懂FSMN VAD的调优逻辑 语音活动检测(VAD)不是“上传→点击→出结果”的黑盒流程。很多用户反馈:“明明有声音,却检测不到”“一句话被切成三段…

作者头像 李华
网站建设 2026/3/5 5:11:32

请求头修改技术:数字内容访问限制的合规性解决方案

请求头修改技术:数字内容访问限制的合规性解决方案 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 问题引入:数字内容获取的现代困境 在信息时代,…

作者头像 李华
网站建设 2026/3/8 1:36:51

数字内容访问方案:技术原理与合规应用指南

数字内容访问方案:技术原理与合规应用指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息时代,用户获取在线内容时常面临各种访问限制。本文将系统解析…

作者头像 李华
网站建设 2026/3/6 9:27:16

5个技巧让你的华硕笔记本性能飙升:G-Helper工具完全掌握指南

5个技巧让你的华硕笔记本性能飙升:G-Helper工具完全掌握指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项…

作者头像 李华
网站建设 2026/3/4 2:48:11

当数字记忆面临消失:如何用GetQzonehistory守护你的青春足迹

当数字记忆面临消失:如何用GetQzonehistory守护你的青春足迹 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 当青春记忆遇上数据洪流 你是否曾有过这样的经历?深…

作者头像 李华