Comment exécuter une commande à l'intérieur d'un virtualenv en utilisant systemd

15

Je crois que cela devrait être simple mais je ne peux pas le faire fonctionner correctement.

Ce sont les commandes que je peux exécuter en ligne de commande:

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

Ces commandes doivent être exécutées dans cet ordre. En raison de virtualenv, du non-exécutable pour crossbar et du script python séparé par la suite, je n'ai pas été en mesure de trouver la meilleure façon de faire fonctionner cela. Mon travail en cours:

[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
la source
1
Pourriez-vous le résoudre encore? Si c'est le cas, comment?
noir

Réponses:

11

Cela ne fonctionne pas parce sourceest une commande shell, donc systemd de ExecStart=ou ExecStartPre=ne les comprendra pas directement ... (BTW, la même chose est vraie pour cdet &&.)

Vous pouvez y parvenir en exécutant explicitement un shell et en exécutant toutes vos commandes ensemble là-bas:

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

Mais une meilleure approche consiste, au lieu de rechercher le script "activate", à utiliser l' pythonexécutable bin/directement dans votre virtualenv.

Si vous regardez le document d'utilisation de virtualenv , vous remarquerez qu'il dit:

ENV/binest créé, où les exécutables vivent - sensiblement un nouveau python . Ainsi, l'exécution d'un script avec #! /path/to/ENV/bin/pythonexécuterait ce script sous le python de ce virtualenv.

En d'autres termes, en supposant que crossbarle script Python que vous souhaitez exécuter nécessite le venv-apvirtualenv, commencez simplement crossbarpar:

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

Et il utilisera automatiquement virtualenv chaque fois qu'il sera invoqué.

Également possible, en invoquant directement l'interpréteur Python depuis virtualenv, avec:

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

(En outre, en ce qui concerne l'exécution dans un répertoire spécifique, le réglage WorkingDirectory=/home/debian/apest meilleur que l'utilisation d'une cdcommande. Vous n'avez pas besoin d'un shell de cette façon, et systemd peut mieux gérer les erreurs pour vous.)

filbranden
la source