systemd服务中Python无法读取I3SOCK环境变量问题排查
问题分析与解决方案
问题根源
你的systemd系统服务(绑定multi-user.target)运行在系统全局会话中,而非用户的图形会话环境里。I3SOCK是i3窗口管理器启动时在用户X会话中生成的环境变量,系统级服务无法访问该会话的环境变量,因此脚本获取不到这个值。而直接运行脚本时,你处于自己的用户图形会话,环境变量自然存在,所以能正常工作。
解决方案一:改用systemd用户服务(推荐)
因为i3是用户会话级程序,对应的辅助脚本也应运行在用户会话环境中,而非系统全局服务。
创建用户服务文件:
~/.config/systemd/user/spliti3.service[Unit] Description=i3窗口自动垂直调整服务 After=graphical-session.target [Service] Type=simple ExecStart=/usr/bin/spliti3 RemainAfterExit=true StandardOutput=append:%h/log0.log StandardError=append:%h/log1.log [Install] WantedBy=graphical-session.target%h等价于用户HOME目录,替代原配置中的$HOMEgraphical-session.target确保服务在图形会话启动后运行,自动继承用户X会话的环境变量(包括I3SOCK)
重新加载并启用用户服务:
systemctl --user daemon-reload systemctl --user enable --now spliti3.service
解决方案二:脚本内主动获取socket路径(无需修改服务类型)
如果坚持使用系统服务,可以修改Python脚本,不依赖环境变量,直接通过命令获取i3的socket路径:
#!/usr/bin/python3 from i3ipc import Connection, Event import subprocess def get_i3_socket_path(): try: result = subprocess.run(['i3', '--get-socket-path'], capture_output=True, text=True, check=True) return result.stdout.strip() except subprocess.CalledProcessError: raise RuntimeError("无法获取i3 socket路径,i3可能未运行或当前用户未启动i3") sock_path = get_i3_socket_path() c = Connection(sock_path)
注意:需确保服务配置的User=raz0229确实是正在运行i3的用户,且系统能找到i3二进制文件。
内容的提问来源于stack exchange,提问作者RAZ0229
相关产品推荐
相关产品推荐

