优先使用 systemd 服务,其次用用户级 .desktop 文件;/etc/rc.local 在 ubuntu 20.04+ 默认禁用且环境不可靠,不推荐。systemd 需正确配置 user=、workingdirectory=、environment=display 和 xauthority,并用绝对路径调用命令;.desktop 文件须放 ~/.config/autostart/ 下,含 exec=、hidden=false 和 x-gnome-autostart-enabled=true;排查需查 journalctl 日志、权限、路径及 gui 环境变量。

直接说结论:优先用 systemd 服务,其次是用户级 .desktop 文件;/etc/rc.local 在 Ubuntu 20.04+ 已默认禁用,别碰它。
用 systemd 服务启动命令(推荐,适合后台/系统级任务)
这是目前最稳定、可调试、支持依赖和自动重启的方式。关键点不是“写完就完”,而是路径、权限、环境变量三者必须对齐。
-
User=必须显式指定,root 用户运行命令加User=root,普通用户(如ubuntu)则写User=ubuntu;不写默认是 root,但 GUI 程序会因缺少DISPLAY失败 -
WorkingDirectory=要填绝对路径,比如/home/ubuntu/scripts;否则脚本里用的相对路径(如./data/config.json)会找不到 - 带图形界面的命令(如
gedit、python3 gui_app.py)必须加环境变量:Environment=DISPLAY=:0和Environment=XAUTHORITY=/home/ubuntu/.Xauthority(路径按实际用户替换) - 命令本身建议用完整路径调用:
ExecStart=/bin/bash /home/ubuntu/scripts/myscript.sh,避免 shell 查找失败 - 启用后务必执行:
sudo systemctl daemon-reload→sudo systemctl enable mycmd.service→sudo systemctl start mycmd.service
用 .desktop 文件启动命令(适合桌面登录后自动运行)
这个方法不依赖 root 权限,也不需要重启系统,改完保存就能在下次登录生效,但只在图形界面登录后触发,且不能保证网络就绪。
- 文件必须放在
~/.config/autostart/目录下,名字任意但后缀必须是.desktop,例如run-on-login.desktop -
Exec=后面不能直接写bash -c "...",要包装成可执行脚本再调用;或者用gnome-terminal -- bash -c "/path/to/cmd; exec bash"弹终端运行(注意空格和引号) - 如果命令需要后台持续运行,加
Terminal=false;如果想看到输出,设为true并确保终端模拟器存在(如gnome-terminal或xfce4-terminal) -
Hidden=false和X-GNOME-Autostart-enabled=true必须存在,否则 GNOME 可能忽略它
为什么 /etc/rc.local 通常失效
Ubuntu 20.04 起默认不启用 rc-local 服务,即使你把命令写进 /etc/rc.local,它也不会执行——因为对应 service 单元被 mask 了。
- 检查状态:
sudo systemctl status rc-local,大概率显示masked - 强行启用要先解 mask:
sudo systemctl unmask rc-local,再创建/etc/systemd/system/rc-local.service手动适配,步骤繁琐且易出错 - 更麻烦的是:
rc.local运行时没有用户会话环境,$HOME、DISPLAY、PATH都不可靠,GUI 命令基本必挂,后台进程也容易因路径错误静默失败 - 除非你在嵌入式或极简 Server 场景下明确控制 init 阶段,否则不建议选这条路
常见失败信号和排查方向
脚本写了、服务启了、也 enable 了,但重启后没反应——八成卡在这几个地方:
- 日志第一:
sudo journalctl -u mycmd.service -n 50 --no-pager,看最后一句是不是failed to start或permission denied - 权限第二:脚本本身没
+x,ls -l /path/to/script.sh确认有-rwxr-xr-x;服务文件也要sudo chown root:root /etc/systemd/system/mycmd.service - 路径第三:所有路径写死,别用
~或$HOME,systemd 不展开它们;cd命令在 service 里无效,靠WorkingDirectory=控制 - GUI 第四:没加
Environment=DISPLAY=:0和XAUTHORITY,或者用户目录写错(比如写成/home/user但实际是/home/ubuntu)
真正难的不是写几行配置,而是让命令在无人值守、无交互、无当前 shell 环境的上下文中稳稳跑起来——每一步都要验证,而不是假设它“应该可以”。











