5分钟搞定Linux开机自启动,测试开机启动脚本保姆级教程
你是不是也遇到过这样的问题:写好了监控脚本、服务程序或者网络配置命令,每次重启系统后都要手动运行一遍?反复操作既费时又容易出错。其实,Linux早就为你准备好了“自动唤醒”机制——只要把命令放进一个特定文件里,系统开机时就会乖乖帮你执行。
本文不讲晦涩的systemd原理,也不堆砌一堆配置参数,就用最直接的方式,带你从零开始,在5分钟内完成一个可验证的开机自启动脚本。全程基于真实环境(Ubuntu 16.04和Tina系统),每一步都可复制、可验证、可回退,连exit 0为什么不能少,都给你讲清楚。
1. 开机自启动的本质:不是魔法,是约定
很多人以为开机自启动很神秘,其实它背后就是一个简单的“约定”:Linux系统在完成初始化、进入多用户模式前,会按固定顺序执行一批脚本。其中,/etc/rc.local就是留给用户使用的“最后一道自定义入口”。
1.1 为什么选/etc/rc.local?
- 兼容性极强:Ubuntu 16.04、Debian系、Tina嵌入式系统等都默认支持
- 无需学习新语法:写法就是普通Shell命令,你平时在终端敲什么,这里就写什么
- 不依赖服务管理器:绕开复杂的systemd unit文件或SysV init脚本,适合快速验证
- 可读性强:所有自启动逻辑集中在一个文件里,排查问题一目了然
注意:Ubuntu 18.04及以后版本默认禁用了
rc.local,但本文目标系统是Ubuntu 16.04和Tina,它们原生支持且默认启用,无需额外启用,省去一步坑。
1.2 它在系统启动流程中的位置
简单说,rc.local是整个启动链的“收尾环节”:
BIOS/UEFI → 内核加载 → init进程启动 → 基础服务就绪 → 网络可用 → /etc/rc.local 执行 → 登录界面出现这意味着:你的命令将在网络、文件系统、基础服务都已就绪后才运行——非常适合需要联网、访问磁盘或调用其他服务的脚本。
2. 动手实操:三步写出可运行的开机启动脚本
我们不搞虚的。下面以一个真实、轻量、可立即验证的示例入手:开机自动给无线网卡wlan0配置IP并启用。这个操作在物联网设备、边缘网关、开发板中非常典型。
2.1 第一步:确认rc.local文件存在且可执行
打开终端,执行:
ls -l /etc/rc.local你应该看到类似输出:
-rwxr-xr-x 1 root root 412 Apr 10 10:23 /etc/rc.local关键看两点:
- 权限中有
x(即可执行),即-rwxr-xr-x - 所有者是
root
如果权限不对(比如只有-rw-r--r--),请立刻修复:
sudo chmod +x /etc/rc.local小心:
rc.local必须是可执行文件,否则系统会跳过它!这是新手最常见的失败原因。
2.2 第二步:编辑rc.local,加入你的命令
使用你喜欢的编辑器(如nano)打开:
sudo nano /etc/rc.local你会看到一个标准模板(可能含注释和exit 0)。请严格按以下格式修改:
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script, simply change the execution # bits. # # By default this script does nothing. # 在这里添加你的命令(注意:必须在 exit 0 之前) ifconfig wlan0 up ifconfig wlan0 192.168.10.100 netmask 255.255.255.0 exit 0关键细节说明:
#!/bin/sh -e:声明使用POSIX shell,-e表示任一命令失败则立即退出(增强健壮性)- 命令位置:所有自定义命令必须写在
exit 0之前,且不能在注释行里 exit 0不可省略:这是告诉系统“本脚本执行成功”。没有它,系统会认为rc.local执行失败,后续可能跳过或报错- 命令要带完整路径(可选但推荐):例如用
/sbin/ifconfig代替ifconfig,避免PATH环境变量未生效导致命令找不到。不过在rc.local上下文中,通常PATH已设置,直接用命令名更简洁
2.3 第三步:保存、重启、验证
- 按
Ctrl+O保存,Ctrl+X退出nano - 立即测试脚本是否语法正确(不重启也能验):
sudo /etc/rc.local如果没报错,说明语法和命令本身没问题。
- 最终验证:重启系统
sudo reboot等待系统完全启动后,登录,运行:
ifconfig wlan0如果看到类似输出:
wlan0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx inet addr:192.168.10.100 Bcast:192.168.10.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1恭喜!你的命令已在开机时自动执行成功。
3. 进阶技巧:让自启动更可靠、更实用
上面的例子只是起点。实际项目中,你可能需要运行Python脚本、启动后台服务、等待网络就绪……这些都能用rc.local优雅解决。
3.1 如何运行Python脚本?
假设你有一个监控脚本/home/pi/monitor.py,想开机就跑:
# 在 rc.local 中添加(注意 & 后台运行,nohup 防止终端关闭中断) cd /home/pi && nohup python3 monitor.py > /var/log/monitor.log 2>&1 &cd /home/pi:先切换到脚本所在目录,避免路径错误nohup:让进程忽略挂起信号,即使SSH断开也不终止> /var/log/monitor.log 2>&1:将标准输出和错误统一重定向到日志文件,方便排查&:后台运行,不阻塞rc.local继续执行
3.2 如何确保网络已就绪再执行?
有些命令(如curl、ping、连接数据库)依赖网络。rc.local虽在网络服务之后运行,但有时网卡驱动或DHCP还没完全就绪。加个简单等待即可:
# 等待 wlan0 获取到IP地址(最多等30秒) COUNTER=0 while [ $COUNTER -lt 30 ]; do if ifconfig wlan0 | grep -q "inet addr"; then break fi sleep 1 COUNTER=$((COUNTER + 1)) done # 此时再执行依赖网络的命令 curl -s http://api.example.com/health > /dev/null3.3 如何调试rc.local不生效?
如果重启后发现命令没运行,别急,按顺序排查:
| 排查项 | 检查命令 | 说明 |
|---|---|---|
| 文件是否可执行 | ls -l /etc/rc.local | 必须含x权限 |
| 是否以 root 运行 | ps aux | grep rc.local | 应显示由 root 执行 |
| 是否有语法错误 | sudo /etc/rc.local | 手动执行看报错 |
| 日志在哪 | sudo journalctl -u rc-local或sudo tail -f /var/log/syslog | grep rc.local | Ubuntu 16.04 主要看 syslog |
| 命令本身是否失败 | 在rc.local中加echo "$(date): start" >> /tmp/rclocal.log | 把日志写入临时文件,确认是否执行到该行 |
实用建议:调试阶段,务必在关键步骤加
echo日志,比如echo "$(date): wlan0 up" >> /tmp/rclocal.log,这是定位问题最快的方法。
4. 常见误区与避坑指南(血泪总结)
刚接触rc.local的人,90%的失败都源于几个经典误区。我们帮你提前踩过坑。
4.1 误区一:“我写了命令,但它没运行”
真相:rc.local里的命令是在root用户环境下执行的,而你的脚本或路径可能是为普通用户配置的。
正确做法:
- 使用绝对路径:
/home/pi/myscript.sh而非./myscript.sh - 显式指定用户(如需):
sudo -u pi /home/pi/myscript.sh - 检查脚本权限:
chmod +x /home/pi/myscript.sh
4.2 误区二:“exit 0删掉也没事吧?”
真相:删掉会导致rc.local执行失败,系统记录错误,且后续命令不会执行。
记住口诀:exit 0是句号,不是可选项。它代表“一切顺利”,缺了就像文章没结尾,系统不知道该不该继续。
4.3 误区三:“我在rc.local里用systemctl start xxx,结果服务没起来”
真相:rc.local执行时,systemd可能尚未完全就绪,或服务依赖关系未满足。
更稳妥做法:
- 直接运行服务二进制:
/usr/bin/myserver --daemon - 或改用真正的systemd service(适合长期项目,但本文聚焦快速验证)
- 如果必须用
systemctl,加短延时:sleep 2 && systemctl start myservice
4.4 误区四:“Tina系统里找不到rc.local”
真相:Tina(全志平台常用嵌入式Linux)默认可能不自带rc.local,但支持创建。
解决方案:
# 创建空文件 sudo touch /etc/rc.local # 添加执行权限 sudo chmod +x /etc/rc.local # 写入标准头和 exit 0 echo '#!/bin/sh -e' | sudo tee /etc/rc.local echo 'exit 0' | sudo tee -a /etc/rc.local然后按前文方法编辑即可。
5. 总结:你已经掌握了Linux开机自启动的核心能力
回顾一下,这5分钟你真正学会了什么:
- 理解本质:
rc.local不是黑科技,而是Linux启动流程中专为用户预留的“自定义终点站” - 掌握流程:确认文件权限 → 编辑添加命令 → 保存 → 重启验证,四步闭环
- 避开大坑:
exit 0必须有、权限x不能少、路径要用绝对、调试靠echo日志 - 拓展应用:运行Python、等待网络、后台守护、嵌入式适配,全部一通百通
你现在完全可以独立为树莓派添加开机摄像头采集、为工控机配置定时数据上报、为开发板预设网络环境——所有这些,都不再需要手动干预。
记住,自动化不是目的,而是让技术回归服务本质的手段。当你把重复劳动交给系统,才能把精力留给真正创造价值的地方。
--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。