我有一个python脚本,使用pygame和pyautogui在我的Raspberry Pi 3 Model B V1.2上通过终端或任何IDLE运行时工作。脚本打开一个网页,并通过pygame读取操纵杆输入。
我希望脚本在网络连接后启动时运行,因此在/etc/systemd/system/中创建了一个服务。
当服务运行时,脚本在使用包括pygame和pyautogui在内的各种库时出现错误。
我的服务如下:
[Unit]
Description=My magic service
After=multi-user.target
Requires=network.target
[Service]
Type=simple
User=pi
ExecStart=/usr/bin/python3 /home/pi/FinalCode.py
Restart=always
StandardOutput=file:/tmp/FinalTests.log
StandardError=inherit
[Install]
WantedBy=multi-user.target
pygame的欢迎信息打印(Hello from The pygame community…等),但是如果返回以下错误:
Traceback (most recent call last):
File "/home/pi/FinalCode.py", line 89, in <module>
for event in pygame.event.get(): # read joystick commands
pygame.error: video system not initialized
然后我注释掉了所有的pygame,但是pyautogui也出现了类似的问题,它返回以下错误:
Traceback (most recent call last):
import pyautogui
File "/home/pi/.local/lib/python3.9/site-packages/pyautogui/__init__.py", line 249, in <module>
import mouseinfo
File "/home/pi/.local/lib/python3.9/site-packages/mouseinfo/__init__.py", line 223, in <module>
_display = Display(os.environ['DISPLAY'])
File "/usr/lib/python3.9/os.py", line 679, in __getitem__
raise KeyError(key) from None
KeyError: 'DISPLAY'
我检查了"sys.prefix"one_answers";sys.base_prefix"无论是在终端还是在服务中,他们都是"us"(我认为这表明它在相同的环境中运行?)service和idle/terminal都通过"/usr/bin/python3">
运行Python 3.9.2如何使systemd服务以与运行脚本的终端或IDLE完全相同的方式运行?
您遇到的基本问题是Systemd单元不知道您希望将这些内容显示在哪里。它缺少DISPLAY
环境变量,该变量在Xorg运行时设置,但在其他情况下不会设置。
我想这个类似问题的答案可能会帮助你。长话短说——让你的服务成为一个用户服务,改变一些依赖关系,然后从你启动Xorg的地方导入变量(登录管理器有一些方法来处理这个问题,但我只使用过startx
,直到我切换到wayland,所以我在这里提供的很少)。
找到一个有效的解决方案,问题如bbenne10所建议的。
事后看来,pyautogui也需要显示,所以之后没有问题。