2026/2/25 5:25:30
网站建设
项目流程
如何制作网站模板,网站开发后乙方把源代码交给甲方,建设部网站首页督办案件,辽宁人社app一直更新一个小脚本解决大问题#xff0c;这才是运维利器
你有没有遇到过这样的场景#xff1a;服务器重启后#xff0c;某个关键服务没起来#xff0c;业务直接中断#xff1b;或者每次手动启动一堆监控脚本、日志清理任务#xff0c;重复操作又累又容易出错#xff1f;其实这才是运维利器你有没有遇到过这样的场景服务器重启后某个关键服务没起来业务直接中断或者每次手动启动一堆监控脚本、日志清理任务重复操作又累又容易出错其实一个不到20行的开机启动脚本就能把这些问题一劳永逸地解决掉。它不依赖复杂工具不增加系统负担却能稳稳托住你的线上服务——这才是真正接地气、可落地、见效快的运维利器。这篇文章不讲高深理论也不堆砌术语。我们就用最朴实的方式带你从零写出一个可靠的开机自启脚本并在CentOS和Ubuntu上都验证通过。无论你是刚接触Linux的新手还是每天和服务器打交道的老运维都能照着做、马上用、不出错。1. 先搞懂一件事开机启动不是“随便放个脚本就行”很多人以为只要把脚本丢进某个目录系统就会自动运行它。但现实是Linux启动过程有明确的阶段划分脚本必须放在对的位置、起对的名字、满足基本规范才能被正确识别和执行。核心就两点脚本得放在/etc/init.d/目录下这是传统SysV init系统的标准位置CentOS 6/7 和 Ubuntu 16.04 的兼容模式都支持脚本本身要带基础控制逻辑至少能响应start、stop、status这三个命令否则系统无法管理它别担心这个要求一点都不难。下面我们就写一个真正可用的mytest.sh它会做一件简单但很典型的事开机时自动创建一个标记文件并记录启动时间。1.1 写一个“能说话”的启动脚本打开终端用你喜欢的编辑器比如nano或vim创建/etc/init.d/mytest.sh#!/bin/bash # chkconfig: 2345 99 01 # description: A simple test service for boot startup # processname: mytest # 定义服务名称和日志路径 SERVICE_NAMEmytest 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你会发现一堆以S或K开头的链接比如S10network、S20sshd、K99grub2。它们的命名规则非常清晰SxxStart表示“启动服务”xx是两位数字代表执行顺序01最早99最晚KxxKill表示“停止服务”同样按数字顺序执行所有这些链接最终都指向/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在脚本开头显式设置 PATHexport PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin5.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/ userbackup-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. 总结小脚本大智慧回看整个过程我们只做了四件事写一个带start/stop/status的标准脚本查清系统运行级别通常是5在/etc/rc5.d/下创建S99mytest软链接用/etc/init.d/rc 5快速验证再reboot终极确认没有安装新软件没有修改内核不依赖云平台甚至不用联网。它纯粹依靠 Linux 最底层、最稳定的启动机制却解决了运维中最高频、最琐碎、最容易出错的问题。真正的运维利器从来不是功能最炫的工具而是最简单、最可靠、最经得起时间考验的那一行命令、一个脚本、一次配置。当你能把这种“小而确定”的能力沉淀成团队的标准实践你就已经走在了自动化运维的正确道路上。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。