Como executar um comando dentro de um virtualenv usando systemd

15

Eu acredito que isso deve ser simples, mas não consigo fazê-lo funcionar corretamente.

Estes são os comandos que eu posso executar na linha de comando:

cd /home/debian/ap

# Start a virtualenv
source venv-ap/bin/activate

# This needs to happen inside the virtualenv and takes ~20 seconds
crossbar start

# Outside the virtualenv, perhaps in a different command line window
python3 /home/debian/myscript.py

Esses comandos precisam ser executados nessa ordem. Devido ao virtualenv, o não executável para barra cruzada e o script python separado posteriormente, não consegui descobrir a melhor maneira de fazer isso funcionar. Meu trabalho atual em andamento:

[Unit]
Description=Start CB
After=network.target

[Service]
Type=simple
User=debian
ExecStartPre=source /home/debian/ap/venv-ap/bin/activate
ExecStart=cd /home/debian/ap/ && crossbar start
Restart=always

[Install]
WantedBy=multi-user.target
sscirrus
fonte
1
Você poderia resolvê-lo ainda? Se sim, como?
preto

Respostas:

11

Isso não funciona porque sourceé um comando do shell, então o systemd ExecStart=ou ExecStartPre=não os entenderá diretamente ... (BTW, o mesmo vale para cde &&.)

Você pode conseguir isso executando um shell explicitamente e executando todos os seus comandos juntos:

ExecStart=/bin/sh -c 'cd /home/debian/ap/ && source venv-ap/bin/activate && crossbar start'

Mas uma abordagem melhor é, em vez de buscar o script "ativar", usar o pythonexecutável bin/diretamente no seu virtualenv.

Se você olhar para o documento de uso do virtualenv , verá que ele diz:

ENV/biné criado, onde os executáveis ​​vivem - notavelmente um novo python . Assim, a execução de um script #! /path/to/ENV/bin/pythonexecutaria esse script no python deste virtualenv.

Em outras palavras, supondo que crossbarseja o script Python que você deseja executar que requer o venv-apvirtualenv, basta começar crossbarcom:

#!/home/debian/ap/venv-ap/bin/python

E ele usará automaticamente o virtualenv sempre que for chamado.

Também é possível invocar o interpretador Python diretamente do virtualenv, com:

ExecStart=/home/debian/ap/venv-ap/bin/python /path/to/crossbar start

(Além disso, em relação executado em um diretório específico, definição WorkingDirectory=/home/debian/apé melhor do que usar um cdcomando. Você não precisa de um shell dessa maneira, e systemd pode fazer melhor manuseio para você erro.)

filbranden
fonte