Ubuntu下Python Tkinter作为systemd服务运行崩溃问题求助
解决Ubuntu下systemctl服务运行Tkinter程序时无法连接DISPLAY的问题
问题核心
虽然服务文件中设置了DISPLAY=:0,但systemd服务缺少X服务器的授权信息(XAUTHORITY),导致触发阈值创建Tkinter窗口时,无法获得访问X图形界面的权限,抛出_tkinter.TclError: couldn't connect to display ":0"错误。
解决方案
1. 更新systemd服务文件,添加XAUTHORITY环境变量
在服务文件的[Service]段中,添加XAUTHORITY环境变量,指向当前用户的X授权文件路径:
[Unit] Description=Storage Monitor Service After=graphical.target Wants=graphical.target [Service] Type=simple User=your_username # 替换为你的实际用户名,比如user Environment=DISPLAY=:0 Environment=XAUTHORITY=/home/your_username/.Xauthority # 对应用户名的授权文件路径 ExecStart=/usr/bin/env python3 /home/your_username/bin/main.py # 替换为你的脚本实际路径 Restart=always RestartSec=5s [Install] WantedBy=graphical.target
修改完成后,重新加载服务配置并重启服务:
sudo systemctl daemon-reload sudo systemctl restart storage_monitor.service
2. 授予服务用户访问X服务器的权限
临时测试可在终端执行以下命令(替换your_username为实际用户名):
xhost +local:your_username
若测试有效,可将该命令添加到用户的~/.xprofile文件中,实现开机自动配置:
echo "xhost +local:your_username" >> ~/.xprofile
3. 优化Python程序的Tkinter初始化逻辑
确保程序在创建Tk实例前,环境变量已正确加载,同时优化窗口创建逻辑避免异常:
import os import tkinter as tk from tkinter import messagebox def center_messagebox(title, message): # 显式加载环境变量(可选,确保服务环境未正确传递时生效) os.environ['DISPLAY'] = ':0' os.environ['XAUTHORITY'] = '/home/your_username/.Xauthority' root = tk.Tk() root.withdraw() # 隐藏主窗口,仅显示消息框 messagebox.showwarning(title, message) root.destroy() # 存储监控逻辑保持不变 def monitor_storage(threshold_percentage=90, check_interval=5): # ... 原监控代码 ... try: # 检查存储使用率逻辑 if usage >= threshold_percentage: center_messagebox("存储告警", f"存储使用率已达{usage}%,请及时清理!") except Exception as e: center_messagebox("Error", f"An error occurred: {e}")
验证
重启服务后,再次用fallocate -l xxG /path/file.txt模拟存储满阈值的场景,查看服务状态:
systemctl status storage_monitor.service
若服务正常运行并弹出告警窗口,则问题解决。
内容的提问来源于stack exchange,提问作者Vlad Belo
相关产品推荐
相关产品推荐

