Tenho um script de shell que define variáveis de ambiente e executa um executável. Parece com isso:
export PATH=$PATH:/some/extra/binaries
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/some/extra/lib
cd /path/to/execuatble
DISPLAY=:0.0 nohup ./app &
Quando executo o script de shell como usuário do terminal, ele não encontra problemas. No entanto, também escrevi um arquivo de serviço que executa um script python que, entre outras coisas, inicia este shell. Exemplo de arquivo python:
import subprocess
import sys
import logging
logger = logging.getLogger(__file__)
logger.setLevel(logging.INFO)
try:
result = subprocess.run(["/path/to/shell/script/script.sh"], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logger.info(result)
except Exception as e:
logger.info("Error starting process: " + str(e), e)
O arquivo python está sendo executado dentro de um serviço systemd com um arquivo de serviço:
[Unit]
Description=App runner Service
After=network.target
[Service]
Environment=PYTHONUNBUFFERED=1
ExecStart=/usr/bin/python3 /path/to/python/script/script.py
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
Quando executo o serviço, vejo o que ele faz com journalctl -f -u servicename
, e posso ver o script de shell falhando quando tento executar o aplicativo com
No protocol specified \n QXcbConnection: Could not connect to display :0.0
Qual é a causa raiz e como posso consertá-la? Estou aberto a alterações do shell script, python ou do arquivo de serviço.
Eu suspeito que tenha a ver com o fato de que o systemd executa isso como root. BTW, eu não tenho ideia de por que eu precisaria de um servidor X já que esse aplicativo não tem nenhuma GUI. Talvez tenha a ver com o fato de que ele usa Qt (nós usamos Qt para um aplicativo não-gui já que queríamos um loop de eventos e utilizar o mecanismo de sinal /slot para passar eventos entre threads e objetos facilmente.
Se isso for relevante, ele roda no Ubuntu 16.04