Ubuntu实现程序开机自动运行
systemd 是 Ubuntu 默认的初始化系统,适合长期运行的服务或脚本。
创建脚本: 假设你有一个需要自动运行的脚本,例如 /home/user/myscript.sh,确保脚本有执行权限:
bash
chmod +x /home/user/myscript.sh
创建 systemd 服务文件: 在 /etc/systemd/system/ 目录下创建一个服务文件,例如 myservice.service:
bash
sudo nano /etc/systemd/system/myservice.service
添加以下内容(根据需要调整):
ini
[Unit]
Description=My Auto Start Script
After=network.target
[Service]
ExecStart=/home/user/myscript.sh
Restart=always
User=user # 替换为你的用户名
Environment=DISPLAY=:0 # 如果需要 GUI 环境
[Install]
WantedBy=multi-user.target
启用服务:
bash
sudo systemctl enable myservice.service
sudo systemctl start myservice.service
检查状态:
bash
sudo systemctl status myservice.service
[Unit]
Description=BridgeSysTask - 启动 Qt GUI 程序
After=network.target graphical.target
[Service]
ExecStart=/home/pi/BridgeSys/linux/arm64_d/runApp.sh
WorkingDirectory=/home/pi/BridgeSys/linux/arm64_d
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=QT_QPA_PLATFORM=xcb
Restart=always
RestartSec=5
User=pi
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=graphical.target
变更说明:
- 替换 After=network.target 为 After=network.target graphical.target,确保图形界面加载完成。
- 替换 WantedBy=multi-user.target 为 WantedBy=graphical.target。
- 添加 Environment=DISPLAY=:0 和 XAUTHORITY=/home/pi/.Xauthority 以支持 X11。
- 添加 QT_QPA_PLATFORM=xcb,与 runApp.sh 保持一致(也可移除,依赖脚本设置)。
- 添加 StandardOutput=journal 和 StandardError=journal 以捕获日志。
保存后,重新加载并重启服务:
bash
sudo systemctl daemon-reload
sudo systemctl restart BridgeSysTask.service
2. 检查服务状态
查看服务状态以确认是否仍然失败:
bash
sudo systemctl status BridgeSysTask.service
检查详细日志:
bash
sudo journalctl -u BridgeSysTask.service -b
3. 验证 X11 环境
确认 X11 服务器运行:
bash
ps aux | grep Xorg
检查 XDG_SESSION_TYPE:
bash
echo $XDG_SESSION_TYPE
- 如果输出为 x11,服务文件的 DISPLAY=:0 和 XAUTHORITY 配置应有效。
- 如果输出为 wayland,QT_QPA_PLATFORM=xcb 可能导致问题。尝试移除服务文件和 runApp.sh 中的 QT_QPA_PLATFORM=xcb,或确保 X11 支持:
bash
sudo apt install xorg
确认 pi 用户的 .Xauthority 文件:
bash
ls -l /home/pi/.Xauthority
如果缺失,尝试以 pi 用户登录图形界面生成 .Xauthority。
4. 调试 runApp.sh 在 systemd 环境
手动模拟 systemd 环境运行脚本:
bash
sudo -u pi env DISPLAY=:0 XAUTHORITY=/home/pi/.Xauthority QT_QPA_PLATFORM=xcb /home/pi/BridgeSys/linux/arm64_d/runApp.sh
如果失败,检查输出错误,可能指向:
- X11 连接问题(cannot connect to X server)。
- 库加载问题(libQt5Core.so: cannot open shared object file)。
- 程序内部错误(segmentation fault 或其他)。
5. 检查 BridgeSys_d 依赖
虽然手动运行正常,但 systemd 环境可能导致库加载问题。再次确认依赖:
bash
ldd /home/pi/BridgeSys/linux/arm64_d/BridgeSys_d
确保 LD_LIBRARY_PATH 中的路径有效:
bash
ls -l /home/pi/BridgeSys/linux/arm64_d/libs
ls -l /home/pi/BridgeSys/linux/arm64_d/plugins
6. 添加调试日志
修改 runApp.sh 以捕获更多信息:
bash
sudo nano /home/pi/BridgeSys/linux/arm64_d/runApp.sh
在 exec "$PRGDIR"/"$EXECUTABLE" 前添加:
bash
echo "Starting BridgeSys_d at $(date)" >> /home/pi/BridgeSysTask.log
exec "$PRGDIR"/"$EXECUTABLE" >> /home/pi/BridgeSysTask.log 2>&1
重启服务并检查日志:
bash
sudo systemctl restart BridgeSysTask.service
cat /home/pi/BridgeSysTask.log
7. 检查权限
确保 pi 用户对所有相关文件有权限:
bash
sudo chown -R pi:pi /home/pi/BridgeSys
sudo chmod -R u+rwX /home/pi/BridgeSys
8. 验证图形会话
systemd 服务可能在用户图形会话启动前运行,导致 X11 不可用。确保 pi 用户已登录图形界面,或尝试以用户级别服务运行:
bash
systemctl --user enable BridgeSysTask.service
为此,需将服务文件移到用户目录:
bash
mkdir -p ~/.config/systemd/user
mv /etc/systemd/system/BridgeSysTask.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user start BridgeSysTask.service
解决步骤
1. 验证 X11 环境
确认系统是否使用 X11:
bash
echo $XDG_SESSION_TYPE
- 如果输出为 x11:
- 检查 X 服务器是否运行:
bash
如果没有 Xorg 进程,启动 X 服务器:ps aux | grep Xorg
bash
startx &
- 确认 .Xauthority 文件存在:
bash
如果缺失,登录图形界面生成:ls -l /home/pi/.Xauthority
bash
xauth generate :0 .
- 检查 X 服务器是否运行:
- 如果输出为 wayland:
- runApp.sh 和服务文件中的 QT_QPA_PLATFORM=xcb 强制使用 X11,可能导致问题。尝试使用 Wayland 插件:
- 编辑 runApp.sh:
bash
将 export QT_QPA_PLATFORM=xcb 改为:sudo nano /home/pi/BridgeSys/linux/arm64_d/runApp.sh
bash
export QT_QPA_PLATFORM=wayland
- 编辑服务文件:
bash
将 Environment=QT_QPA_PLATFORM=xcb 改为:sudo nano /etc/systemd/system/BridgeSysTask.service
ini
或完全移除此行,依赖脚本设置。Environment=QT_QPA_PLATFORM=wayland
- 重新加载并重启服务:
bash
sudo systemctl daemon-reload
sudo systemctl restart BridgeSysTask.service
- 编辑 runApp.sh:
- runApp.sh 和服务文件中的 QT_QPA_PLATFORM=xcb 强制使用 X11,可能导致问题。尝试使用 Wayland 插件:
2. 测试 systemd 环境
模拟 systemd 环境运行脚本,验证 X11 配置:
bash
sudo -u pi env DISPLAY=:0 XAUTHORITY=/home/pi/.Xauthority QT_QPA_PLATFORM=xcb /home/pi/BridgeSys/linux/arm64_d/runApp.sh
- 如果失败,记录具体错误。
- 如果成功,说明服务文件配置可能仍不完整。
3. 检查 X11 依赖
确保 X11 相关库已安装:
bash
sudo apt update
sudo apt install libqt5xcbqpa5 libxcb-xinerama0 libxcb-xinput0 libx11-xcb1 xorg
检查 BridgeSys_d 的依赖:
bash
ldd /home/pi/BridgeSys/linux/arm64_d/BridgeSys_d
如果有 not found 的库,安装缺失依赖:
bash
sudo apt install libxcb1 libxcb-xfixes0 libxcb-shape0
4. 确保图形界面已启动
After=graphical.target 要求图形界面加载完成。确认显示管理器运行:
bash
sudo systemctl status display-manager
如果未运行,启用并启动:
bash
sudo systemctl enable display-manager
sudo systemctl start display-manager
常用显示管理器包括 lightdm 或 gdm3,确认安装:
bash
sudo apt install lightdm
5. 运行用户级服务
系统服务可能在用户图形会话启动前运行,导致 X11 不可用。尝试以 pi 用户的 systemd 用户服务运行:
bash
mkdir -p ~/.config/systemd/user
cp /etc/systemd/system/BridgeSysTask.service ~/.config/systemd/user/
编辑用户服务文件,移除 User=pi(用户服务默认以当前用户运行):
bash
nano ~/.config/systemd/user/BridgeSysTask.service
确保内容为:
ini
[Unit]
Description=BridgeSysTask - 启动 Qt GUI 程序
After=network.target graphical.target
[Service]
ExecStart=/home/pi/BridgeSys/linux/arm64_d/runApp.sh
WorkingDirectory=/home/pi/BridgeSys/linux/arm64_d
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=QT_QPA_PLATFORM=xcb
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=graphical.target
启用并启动用户服务:
bash
systemctl --user daemon-reload
systemctl --user enable BridgeSysTask.service
systemctl --user start BridgeSysTask.service
检查状态:
bash
systemctl --user status BridgeSysTask.service
6. 捕获详细日志
修改 runApp.sh 添加日志:
bash
sudo nano /home/pi/BridgeSys/linux/arm64_d/runApp.sh
在 exec "$PRGDIR"/"$EXECUTABLE" 前添加:
bash
echo "Starting BridgeSys_d at $(date)" >> /home/pi/BridgeSysTask.log
exec "$PRGDIR"/"$EXECUTABLE" >> /home/pi/BridgeSysTask.log 2>&1
重启服务并检查日志:
bash
sudo systemctl restart BridgeSysTask.service
cat /home/pi/BridgeSysTask.log
7. 禁用 Wayland(如果适用)
如果 XDG_SESSION_TYPE 为 wayland 且无法切换到 Wayland 插件,强制系统使用 X11:
- 编辑显示管理器配置(例如 lightdm):
bash
添加或修改:sudo nano /etc/lightdm/lightdm.conf
ini
[Seat:*]
session-type=x11
- 重启显示管理器:
bash
sudo systemctl restart lightdm
下一步
请执行以下步骤并提供结果:
- 检查 XDG_SESSION_TYPE:
bash
echo $XDG_SESSION_TYPE
- 运行模拟 systemd 环境的命令:
bash
sudo -u pi env DISPLAY=:0 XAUTHORITY=/home/pi/.Xauthority QT_QPA_PLATFORM=xcb /home/pi/BridgeSys/linux/arm64_d/runApp.sh
- 检查 .Xauthority 文件:
bash
ls -l /home/pi/.Xauthority
- 检查服务状态和日志:
bash
sudo systemctl status BridgeSysTask.service
sudo journalctl -u BridgeSysTask.service -b
- 如果尝试用户服务,运行:
bash
systemctl --user status BridgeSysTask.service