如何优雅地添加开机命令?测试脚本给你答案
在Linux系统中,尤其是Ubuntu这类桌面或服务器环境中,我们常常需要让某些脚本或命令在系统启动时自动运行。比如:初始化环境变量、启动监控服务、挂载磁盘、运行自定义程序等。如果每次重启都要手动执行一遍,显然效率低下。
本文将围绕一个简单的测试脚本,带你深入理解如何安全、稳定、可维护地设置开机自启命令,并对比几种主流方法的优劣,帮助你选择最适合当前场景的方式。
1. 准备测试脚本
为了验证不同方案是否生效,我们先准备一个简单的测试脚本test.sh,它会在指定目录下执行ls并输出提示信息。
1.1 创建脚本文件
nano ~/Desktop/test.sh输入以下内容:
#!/bin/bash # test.sh - 开机启动测试脚本 cd /home/$USER/Desktop/ ls echo "OK! 测试脚本已成功执行" exit 0注意:请根据实际用户名替换
$USER,或者直接写死路径如/home/yourname/Desktop/。
1.2 赋予可执行权限
chmod +x ~/Desktop/test.sh你可以先手动运行一次确认功能正常:
~/Desktop/test.sh看到输出文件列表和"OK!"提示即表示脚本无误。
2. 方法一:使用 /etc/init.d + update-rc.d(SysVinit 风格)
这是传统 SysVinit 系统的经典方式,虽然 Ubuntu 已转向 systemd,但该方法仍兼容支持。
2.1 将脚本移入系统服务目录
sudo mv ~/Desktop/test.sh /etc/init.d/2.2 设置执行权限
sudo chmod 755 /etc/init.d/test.sh建议不要用
777,出于安全考虑,仅需保证 root 可读可执行即可。
2.3 注册为开机启动项
sudo update-rc.d test.sh defaults这会为脚本创建软链接到各个运行级别对应的 rcN.d 目录(如 rc2.d、rc5.d),默认优先级为 S20(启动)和 K20(关闭)。
自定义启动顺序(可选)
如果你希望这个脚本晚一点执行(例如依赖网络或其他服务),可以指定优先级数字:
sudo update-rc.d test.sh defaults 90数值越大,启动越晚。例如S90test.sh表示它是较晚启动的服务。
2.4 移除开机启动
若要取消注册:
sudo update-rc.d -f test.sh remove-f参数表示强制删除相关符号链接。
2.5 适用场景与注意事项
- 适合老旧系统或习惯 SysVinit 的运维人员
- 不推荐用于新项目,已被 systemd 取代
- 脚本需自行处理依赖关系(如网络就绪)
- ❌ 若系统完全使用 systemd,则此方法可能被忽略或不稳定
3. 方法二:通过图形界面添加启动程序(gnome-session-properties)
对于桌面用户来说,最直观的方法是利用 GNOME 桌面提供的“启动应用程序”管理器。
3.1 打开启动应用程序设置
打开终端,运行:
gnome-session-properties你会看到如下窗口:

点击【添加】按钮。
3.2 添加自定义命令
填写以下字段:
- 名称:Test Script
- 命令:
gnome-terminal -x bash -c "/home/$USER/Desktop/test.sh; read" - 注释:运行桌面测试脚本
使用
read是为了让终端保持打开状态,便于观察输出结果。生产环境可去掉。
替代写法(后台静默执行)
如果你不希望弹出终端窗口:
/home/$USER/Desktop/test.sh或将输出重定向:
bash -c "/home/$USER/Desktop/test.sh >> /tmp/startup.log 2>&1"3.3 间接方式:修改 ~/.bashrc(慎用)
有些教程建议将命令写入~/.bashrc,因为每次打开终端都会加载该文件。
例如:
echo "/home/$USER/Desktop/test.sh" >> ~/.bashrc但这并不是真正的“开机启动”,而是“每次打开终端时运行”,容易造成重复执行,且无法确保只运行一次。
🚫 不推荐此法作为开机启动手段,仅适用于特定交互式场景。
3.4 优点与局限
- 操作简单,适合普通桌面用户
- 图形化操作,无需记忆命令
- 仅在用户登录后触发,不能用于系统级服务
- 依赖桌面环境,服务器无GUI时不适用
4. 方法三:使用 rc.local(经典通用方案)
rc.local是一个传统的系统级启动脚本,在大多数 Linux 发行版中都存在,通常由 systemd 兼容性服务调用。
4.1 编辑 rc.local 文件
首先确保文件存在:
sudo nano /etc/rc.local典型内容如下:
#!/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. # Your command here exit 0在exit 0之前插入你的命令:
su - $USER -c "cd /home/$USER/Desktop && ./test.sh"使用
su - $USER是为了以指定用户身份执行脚本,避免权限问题。
完整示例:
#!/bin/sh -e su - yourusername -c "cd /home/yourusername/Desktop && ./test.sh" exit 04.2 确保 rc-local 服务启用(Ubuntu 20.04+)
新版 Ubuntu 默认未启用rc.local服务,需手动激活:
# 创建 systemd 服务覆盖 sudo systemctl enable rc-local如果没有/etc/systemd/system/rc-local.service,可手动创建:
sudo nano /etc/systemd/system/rc-local.service写入:
[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target然后启用并启动服务:
sudo systemctl enable rc-local sudo systemctl start rc-local4.3 注意事项
- 兼容性强,几乎所有 Linux 都支持
- 可执行系统级命令,适合早期初始化任务
- 脚本在用户登录前运行,因此 GUI 程序或依赖 X11 的操作可能失败
- 错误不易排查,建议添加日志输出:
su - yourusername -c "cd /home/yourusername/Desktop && ./test.sh >> /tmp/rc_local_boot.log 2>&1"5. 推荐方案:使用 systemd 服务(现代最佳实践)
尽管原始参考文档未提及,但从工程化和稳定性角度出发,systemd 服务是最推荐的现代做法。
5.1 创建自定义 service 文件
sudo nano /etc/systemd/system/test-startup.service写入以下内容:
[Unit] Description=Run Test Startup Script After=multi-user.target [Service] Type=oneshot User=yourusername ExecStart=/home/yourusername/Desktop/test.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target请将
yourusername替换为真实用户名。
5.2 启用并测试服务
# 重新加载 systemd 配置 sudo systemctl daemon-reexec # 启用开机启动 sudo systemctl enable test-startup.service # 立即测试运行 sudo systemctl start test-startup.service # 查看执行状态 sudo systemctl status test-startup.service5.3 日志查看
journalctl -u test-startup.service --since "1 hour ago"5.4 优势总结
- 完全集成 systemd 生态,标准规范
- 支持依赖控制(如
After=network.target) - 可指定运行用户、环境变量、超时等
- 易于调试和监控(通过
journalctl) - 推荐用于服务器、工控机、自动化部署场景
6. 各方法对比总结
| 方法 | 是否需要GUI | 执行时机 | 权限级别 | 推荐度 | 适用场景 |
|---|---|---|---|---|---|
/etc/init.d + update-rc.d | 否 | 系统启动早期 | root | ☆ | 兼容旧系统 |
gnome-session-properties | 是 | 用户登录后 | 用户 | 桌面用户日常使用 | |
~/.bashrc修改 | 是 | 每次开终端 | 用户 | ☆☆ | ❌ 不推荐 |
rc.local | 否 | 登录前,系统初始化末期 | root 或切换用户 | 快速部署、通用脚本 | |
| systemd service | 否 | 灵活可控(可设依赖) | root/指定用户 | 生产环境首选 |
7. 实践建议与避坑指南
7.1 路径问题一定要绝对化
避免使用相对路径,所有脚本调用应使用完整路径:
/home/username/Desktop/test.sh而不是:
./test.sh7.2 添加日志输出便于排错
无论哪种方法,建议在脚本中加入日志记录:
#!/bin/bash { echo "[$(date)] 开始执行测试脚本" cd /home/$USER/Desktop/ ls echo "OK! 脚本执行完成" } >> /tmp/test_startup.log 2>&17.3 处理环境变量缺失问题
某些环境下$HOME、$DISPLAY等变量可能为空,特别是rc.local或 systemd 中运行 GUI 程序时。
解决办法:显式声明:
export HOME=/home/yourusername export DISPLAY=:07.4 工控机自动登录配置(补充说明)
若需实现无人值守启动,可在 Settings → Users 中开启“自动登录”,确保桌面环境能顺利加载,从而使gnome-session-properties类脚本正常运行。
8. 总结
通过本文的详细演示,你应该已经掌握了多种为 Linux 系统添加开机命令的方法,并了解了它们各自的适用边界。
- 如果你是普通桌面用户,追求简便快捷,推荐使用gnome-session-properties。
- 如果你在做嵌入式设备或工控机开发,且系统有桌面环境,也可以结合自动登录 + 图形化启动项。
- 如果你需要更高的可靠性与可维护性,尤其是服务器或长期运行设备,请务必采用systemd 服务方式,这是目前最标准、最强大的解决方案。
- 对于临时需求或快速验证,
rc.local依然是一个简单有效的选择。
最终记住一句话:
越自动化,越需要日志;越关键,越要用 systemd。
合理选择方法,让你的开机脚本既“优雅”又“可靠”。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。