Eu acredito que isso deve ser simples, mas não consigo fazê-lo funcionar corretamente.
Estes são os comandos que 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 devem ser executados nessa ordem. Devido ao virtualenv, o não executável para crossbar 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
Isso não funciona porque
source
é um comando shell, então systemd'sExecStart=
ouExecStartPre=
não os entenderá diretamente ... (BTW, o mesmo é verdadeiro paracd
e o&&
.)Você pode conseguir isso executando um shell explicitamente e executando todos os seus comandos juntos:
Mas uma abordagem melhor é, em vez de obter o script "ativar", usar o
python
executávelbin/
diretamente no seu virtualenv.Se você olhar o documento de uso do virtualenv , notará que diz:
Em outras palavras, assumindo que
crossbar
o script Python que você deseja executar requer ovenv-ap
virtualenv, simplesmente comececrossbar
com:E ele usará automaticamente o virtualenv sempre que for invocado.
Também é possível invocar o interpretador Python do virtualenv diretamente, com:
(Além disso, em relação à execução em um diretório específico, a configuração
WorkingDirectory=/home/debian/ap
é melhor do que usar umcd
comando. Você não precisa de um shell dessa forma e o systemd pode fazer um melhor tratamento de erros para você.)Eu quero iterar na segunda parte da resposta de @filbranden
Não execute coisas no venv sem ativá-lo! Para ser justo, a documentação também é enganosa. Ativar o venv permite separar o diretório de trabalho do caminho do python (e dos pacotes venv-ed), o que é obrigatório com bastante frequência: você não deseja executar/colocar algo diretamente no venv bin, mas instalou alguns dependências do script para ele.
Considere o seguinte cenário (que aposto que é um dos mais comuns):
Se você quiser trabalhar no aplicativo a partir do repositório git, deseja que sua pasta esteja intacta, exceto suas modificações de código significativas. Você não gostaria de mudar shebang. Você pode colocar todo o venv em um subdiretório no repositório clonado e gitignorá-lo para manter tudo organizado, mas então:
Além disso, talvez você não queira executar o python diretamente, mas, por exemplo: gunicorn, e você colocou o webapp
/srv
enquanto o venv está em/var/lib
.Não ativar um venv não é um bom hábito , eu me pergunto como aquele parágrafo idiota chegou aos documentos venv oficiais. Sim, ativá-lo não é necessário em alguns casos, exceto em muitos cenários do mundo real! - Eu defendo.
ExecStartPre
não funcionará para fornecer venv de qualquer maneira, pois ele é executado em um shell diferente doExecStart
comando 's, portanto, as variáveis de ambiente não estarão corretas no último.Aconselho definir o venv PATH com
Environment