树莓派rc.local执行pynput脚本与终端运行结果不一致
差异原因
两种执行方式结果不一致,核心是rc.local的运行环境、运行时机和手动终端执行存在本质区别:
- rc.local属于系统早期启动项,以root身份运行,执行节点远早于普通用户的图形会话(X Server)初始化完成时间。固定
sleep 60无法适配不同设备的启动耗时,很多场景下60秒后X服务还没完成启动、或者还没完成会话权限绑定,此时连接X服务必然失败。 - 原脚本存在环境变量传递漏洞:
DISPLAY=:0 python -c 'import pynput'这行的环境变量仅对当前测试用的python进程生效,后续启动Hid.py的进程没有继承DISPLAY变量。手动在终端执行时,终端本身已经在图形会话下自动加载了DISPLAY等X相关环境变量,所以这个漏洞不会触发。 - X Server默认会拒绝非当前会话用户、root用户的连接请求,rc.local以root身份运行时,即使DISPLAY变量配置正确,没有提前放通X权限也会被拒绝连接。
解决方案
第一步:修正原有bash脚本
把固定sleep改成X服务状态轮询,补全X权限放通逻辑,保证环境变量正确传递给所有后续进程,修正后脚本如下:
#!/bin/bash # 轮询等待X服务完全就绪,比固定sleep更可靠 while ! xset q &>/dev/null; do sleep 2 done export DISPLAY=:0 # 放通本地用户的X服务连接权限 xhost +local: chmod 666 /dev/hidg0 # 用和主脚本相同的python3解释器验证pynput导入 python3 -c 'import pynput' # 显式指定DISPLAY变量启动主脚本 DISPLAY=:0 python3 /home/pi/Hid.py |& tee -a /home/pi/test.log exit 0
给脚本加可执行权限:
chmod +x /home/pi/bash.sh
第二步:替换自启方式(二选一即可,优先选第一种)
方式1:桌面会话自启(和手动执行环境完全一致,稳定性最高)
在pi用户的自启目录下新建desktop入口:mkdir -p /home/pi/.config/autostart nano /home/pi/.config/autostart/hid-start.desktop写入以下内容:
[Desktop Entry] Type=Application Name=HID Runner Exec=/bin/bash /home/pi/bash.sh保存退出后,脚本会在pi用户的图形桌面完全加载后自动运行,天然继承所有图形会话需要的环境变量,不会出现X连接错误。
方式2:systemd系统级自启
新建systemd服务文件:nano /etc/systemd/system/hid-runner.service写入以下内容:
[Unit] Description=Run HID pynput script After=graphical.target [Service] User=pi Environment="DISPLAY=:0" Environment="XAUTHORITY=/home/pi/.Xauthority" ExecStart=/bin/bash /home/pi/bash.sh Restart=on-failure [Install] WantedBy=graphical.target保存退出后执行以下命令启用服务:
systemctl daemon-reload systemctl enable hid-runner.service该配置会等图形界面启动完成后,以pi用户身份运行脚本,提前注入X服务需要的环境变量,避免rc.local的时序和权限问题。
内容的提问来源于stack exchange,提问作者suljic
相关产品推荐
相关产品推荐

