news 2026/5/15 7:17:43

再也不怕忘记启动服务,这个脚本让我彻底解放双手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
再也不怕忘记启动服务,这个脚本让我彻底解放双手

再也不怕忘记启动服务,这个脚本让我彻底解放双手

你有没有过这样的经历:辛辛苦苦部署好一个服务,测试运行一切正常,信心满满地关机睡觉——结果第二天一早打开电脑,发现服务根本没起来?手动启动、检查日志、排查端口冲突……一套操作下来,半小时没了。更糟的是,如果这是个无人值守的边缘设备或远程服务器,一次遗漏就可能导致整个业务链路中断。

别担心,这不是你的错,而是缺少一个真正可靠的开机自启机制。今天这篇文章不讲复杂原理,不堆晦涩参数,只用一个清晰、稳定、跨发行版的实践方案,帮你把“每次开机都要手动敲命令”这件事,从待办清单里永久划掉。

本文基于真实部署场景验证,适用于 CentOS 7/8 和 Ubuntu 18.04/20.04/22.04 等主流 Linux 发行版,无需安装额外工具,不依赖 systemd 的高级特性,兼容传统 SysV init 和 modern hybrid 模式。所有步骤均可复制粘贴执行,5 分钟内完成配置。

1. 明确目标:我们要自动化什么

在动手前,先理清核心诉求:

  • 服务必须随系统启动自动运行,不是用户登录后才启动
  • 失败时有明确反馈,不能静默退出或卡死
  • 支持手动启停控制,方便日常维护和调试
  • 不干扰其他服务依赖关系,避免因启动顺序导致失败

我们不追求“最炫酷”的写法,而要“最稳当”的落地。因此,本文采用经典的/etc/init.d/+rcN.d/软链接方式——它被验证了二十多年,至今仍是生产环境首选方案之一。

提示:虽然 systemd 已成主流,但很多企业级镜像(尤其是轻量容器化部署)仍保留 SysV 兼容层。本方案正是为这类真实场景而生,不是教科书里的“理论最优解”,而是运维一线的“经验最优解”。

2. 准备你的启动脚本

我们以一个典型的服务为例:一个监听本地 8080 端口的 Python HTTP 服务(实际可替换为你自己的任何程序)。脚本需具备标准的start/stop/status接口,这是 SysV init 识别和管理服务的基础。

2.1 创建可执行脚本文件

在终端中执行以下命令,创建/etc/init.d/mytest.sh

sudo tee /etc/init.d/mytest.sh << 'EOF' #!/bin/bash # chkconfig: 2345 99 01 # description: My Test Service - a simple HTTP server for demo # processname: mytest DAEMON="/usr/bin/python3" DAEMON_OPTS="/opt/mytest/app.py" PIDFILE="/var/run/mytest.pid" LOGFILE="/var/log/mytest.log" start() { echo -n "Starting mytest service: " if [ -f $PIDFILE ]; then PID=$(cat $PIDFILE) if kill -0 $PID > /dev/null 2>&1; then echo "already running (PID: $PID)" return 0 fi fi # 启动服务并记录 PID $DAEMON $DAEMON_OPTS >> $LOGFILE 2>&1 & echo $! > $PIDFILE echo "done (PID: $(cat $PIDFILE))" } stop() { echo -n "Stopping mytest service: " if [ -f $PIDFILE ]; then PID=$(cat $PIDFILE) if kill -15 $PID > /dev/null 2>&1; then # 等待优雅退出 for i in {1..10}; do if ! kill -0 $PID > /dev/null 2>&1; then rm -f $PIDFILE echo "stopped" return 0 fi sleep 1 done # 强制终止 kill -9 $PID 2>/dev/null rm -f $PIDFILE echo "killed" else echo "not running" fi else echo "not running" fi } status() { if [ -f $PIDFILE ]; then PID=$(cat $PIDFILE) if kill -0 $PID > /dev/null 2>&1; then echo "mytest is running (PID: $PID)" return 0 else echo "mytest is not running (stale PID file)" rm -f $PIDFILE fi else echo "mytest is not running" fi } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; status) status ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 EOF

2.2 设置权限并验证语法

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

此时应输出mytest is not running。如果你已有自己的服务程序,只需修改脚本中的DAEMONDAEMON_OPTS变量即可,其余逻辑通用。

小技巧:脚本开头的# chkconfig:行是给chkconfig工具用的(CentOS),Ubuntu 用户可忽略,但它不影响功能,保留无害且增强兼容性。

3. 确认系统默认运行级别

不同发行版默认启动级别略有差异,这决定了服务该放入哪个rcN.d/目录。我们用一条命令快速确认:

runlevel

输出类似N 53,其中第二个数字就是当前默认运行级别(5表示图形界面,3表示多用户文本模式)。绝大多数服务器环境使用35,桌面环境多为5

注意:Ubuntu 18.04+ 默认使用 systemd,但/etc/rc*.d/仍被保留并由systemd-sysv-generator自动映射。所以即使你看到systemd,这套方案依然有效。

4. 建立启动软链接

根据上一步得到的运行级别(假设为5),进入对应目录并创建软链接:

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

这里S99mytest的含义是:

  • S表示Start(启动)
  • 99是启动优先级,数值越大越晚执行(确保数据库、网络等基础服务已就绪)
  • mytest是服务标识名,清晰易读

如果你的runlevel输出是3,则执行:

cd /etc/rc3.d/ sudo ln -sf /etc/init.d/mytest.sh S99mytest

验证是否成功:运行ls -l S99*,应看到类似S99mytest -> /etc/init.d/mytest.sh的输出。注意使用-sf参数强制覆盖,避免重复创建。

5. 测试与验证:三步确认万无一失

光配置完还不够,必须通过真实测试闭环验证。我们分三步走:

5.1 手动触发启动流程

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

应看到类似mytest is running (PID: 12345)的输出。同时检查端口是否监听:

sudo ss -tuln | grep :8080

若看到LISTEN状态,说明服务已正确运行。

5.2 模拟系统重启(不真重启)

为避免中断工作,我们用telinit命令模拟切换运行级别(仅限支持 SysV 的系统):

# 切换到单用户模式再切回,触发 rc scripts 重载 sudo telinit 1 sudo telinit 5

然后再次检查状态:

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

如果仍显示运行中,说明软链接已生效。

5.3 真机重启验证(推荐在测试环境)

最后,在可控环境中执行一次完整重启:

sudo reboot

机器重启后,等待 1–2 分钟,SSH 登录,立即执行:

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

成功标志:输出mytest is running,且你的服务功能完全可用(如能 curl 通 8080 端口)。

实战提醒:首次部署建议在虚拟机或测试服务器进行。若服务启动失败,查看/var/log/mytest.logjournalctl -u mytest(systemd 环境)快速定位问题。

6. 日常维护与排错指南

配置不是一劳永逸,掌握几个关键命令,让你随时掌控服务状态:

6.1 快速启停与状态检查

# 启动 sudo service mytest start # 停止 sudo service mytest stop # 重启(推荐用于配置更新后) sudo service mytest restart # 查看状态 sudo service mytest status

注:service命令是/etc/init.d/脚本的统一入口,比直接调用脚本更规范,也兼容 systemd。

6.2 常见问题与解决思路

现象可能原因解决方法
service mytest status显示 not running,但手动start成功脚本未写入rc5.d/或链接错误检查ls -l /etc/rc5.d/S99*,确认软链接指向正确路径
重启后服务未启动,但手动start正常启动顺序冲突(如依赖的数据库未就绪)S99mytest改为S98mytest或更低序号,或在脚本start()中加入sleep 3等待
日志中报Permission denied脚本无执行权限或路径权限不足sudo chmod +x /etc/init.d/mytest.sh,确保DAEMON_OPTS指向的文件可读
PID file exists but process not found上次异常退出未清理 PID 文件sudo rm -f /var/run/mytest.pid,再start

6.3 卸载方案(安全删除)

如需移除开机自启,只需两步:

# 1. 删除软链接 sudo rm -f /etc/rc3.d/S99mytest /etc/rc5.d/S99mytest # 2. 删除脚本(可选) sudo rm -f /etc/init.d/mytest.sh sudo rm -f /var/log/mytest.log /var/run/mytest.pid

整个过程无残留,干净利落。

7. 进阶建议:让自动化更可靠

以上方案已足够应对 95% 的场景,但如果你希望进一步提升健壮性,可考虑以下三点轻量优化:

7.1 添加健康检查钩子

在脚本start()函数末尾加入简单连通性验证:

# 启动后等待 2 秒,检查端口是否就绪 sleep 2 if ! nc -z 127.0.0.1 8080; then echo "WARNING: service started but port 8080 not responding" # 可选:发送告警邮件或写入日志 fi

7.2 使用 logrotate 管理日志

避免日志文件无限增长,创建/etc/logrotate.d/mytest

/var/log/mytest.log { daily missingok rotate 14 compress delaycompress notifempty create 644 root root }

7.3 统一服务管理(systemd 用户)

如果你确定只用 systemd,可将上述脚本转换为原生 service 文件(非必需,但更现代):

sudo tee /etc/systemd/system/mytest.service << 'EOF' [Unit] Description=My Test Service After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/mytest ExecStart=/usr/bin/python3 /opt/mytest/app.py Restart=on-failure RestartSec=10 StandardOutput=append:/var/log/mytest.log StandardError=append:/var/log/mytest.log [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable mytest sudo systemctl start mytest

注意:此方案与前述 SysV 方案互斥,请勿同时启用。选择一种并坚持使用即可。

8. 总结:从“记得做”到“自动做”的思维转变

到这里,你已经拥有了一个经过实战检验的开机自启解决方案。它不依赖云平台、不绑定特定框架、不引入新组件,纯粹利用 Linux 系统自带能力,却解决了最让人头疼的运维痛点。

回顾整个过程,真正的价值不仅在于那几行命令,而在于建立了一种自动化思维:

  • 服务即配置:把服务生命周期(启停、状态、日志)封装进脚本,它就成了可版本化、可复用的资产
  • 启动即契约S99mytest不只是一个文件名,它是你和系统之间的一份约定——“请在我需要时,准时唤醒它”
  • 稳定即习惯:不再靠记忆,而是靠机制;不再临时救火,而是提前设防

下次当你部署一个新的 API 服务、一个数据采集器、一个本地 AI 推理节点时,只需复制这份脚本模板,改几处路径,加一行软链接——你的服务,从此真正“活”在系统里。


获取更多AI镜像

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

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

Qwen3-1.7B性能评测:MoE架构下GPU算力优化实测数据

Qwen3-1.7B性能评测&#xff1a;MoE架构下GPU算力优化实测数据 1. 模型背景与定位&#xff1a;为什么是Qwen3-1.7B&#xff1f; Qwen3-1.7B不是传统意义上的“小模型”&#xff0c;而是一款在MoE&#xff08;Mixture of Experts&#xff09;架构下精心设计的轻量级专家模型。…

作者头像 李华
网站建设 2026/5/9 14:46:12

企业级语音质检方案:FSMN VAD在电话录音分析中的应用

企业级语音质检方案&#xff1a;FSMN VAD在电话录音分析中的应用 1. 为什么电话录音分析需要专业VAD&#xff1f; 你有没有遇到过这样的情况&#xff1a;客服中心每天产生上万通电话录音&#xff0c;但人工抽检率不到5%&#xff0c;漏检大量服务问题&#xff1b;质检团队花80…

作者头像 李华
网站建设 2026/5/9 18:36:21

小白也能用!Qwen-Image-Layered图层拆分实战教程

小白也能用&#xff01;Qwen-Image-Layered图层拆分实战教程 你是否遇到过这样的困扰&#xff1a;一张精心设计的海报&#xff0c;想单独调整文字颜色却怕误伤背景&#xff1f;一个产品图里人物和背景粘连紧密&#xff0c;抠图后边缘毛糙、反复重试&#xff1f;或者想把旧照片…

作者头像 李华
网站建设 2026/5/3 7:33:06

2024年AI语音应用趋势:Emotion2Vec+ Large开源模型部署入门必看

2024年AI语音应用趋势&#xff1a;Emotion2Vec Large开源模型部署入门必看 1. 为什么Emotion2Vec Large值得你今天就上手 你有没有想过&#xff0c;一段3秒的语音里藏着多少情绪密码&#xff1f;不是靠猜&#xff0c;而是用AI真正“听懂”——愤怒的紧绷、惊喜的上扬、疲惫的…

作者头像 李华
网站建设 2026/5/8 18:05:38

基于Java+SpringBoot+SSM河南特色美食分享系统(源码+LW+调试文档+讲解等)/河南美食推荐系统/河南特色小吃平台/河南美食分享平台/河南地方美食系统/河南特色美食介绍系统

博主介绍 &#x1f497;博主介绍&#xff1a;✌全栈领域优质创作者&#xff0c;专注于Java、小程序、Python技术领域和计算机毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2025-2026年最新1000个热门Java毕业设计选题…

作者头像 李华
网站建设 2026/5/9 1:59:26

Paraformer-large节能模式:空闲时自动降低GPU功耗

Paraformer-large节能模式&#xff1a;空闲时自动降低GPU功耗 语音识别模型在实际部署中&#xff0c;常常面临一个被忽视却影响深远的问题&#xff1a;GPU资源持续占用带来的隐性成本。尤其当Paraformer-large这类高性能ASR模型以离线方式长期运行Web服务时&#xff0c;即使界…

作者头像 李华