Jak uruchomić polecenie w virtualenv za pomocą systemd

15

Uważam, że powinno to być proste, ale nie mogę sprawić, by działało poprawnie.

Oto polecenia, które mogę uruchomić w wierszu poleceń:

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

Te polecenia muszą być wykonane w tej kolejności. Ze względu na virtualenv, nie wykonywalny dla poprzeczki i później oddzielny skrypt Pythona, nie byłem w stanie znaleźć najlepszego sposobu, aby to uruchomić. Moja obecna praca w toku:

[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
źródło
1
Czy możesz to jeszcze rozwiązać? Jeśli tak to jak?
czarny

Odpowiedzi:

11

To nie działa, ponieważ sourcejest polecenie powłoki, tak Systemd użytkownika ExecStart=lub ExecStartPre=nie zrozumie je bezpośrednio ... (BTW, to samo odnosi się do cda &&).

Można to osiągnąć, uruchamiając powłokę jawnie i uruchamiając wszystkie polecenia razem:

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

Ale lepszym podejściem jest zamiast pozyskiwania skryptu „aktywować” bezpośrednie użycie pythonpliku wykonywalnego w bin/twoim virtualenv.

Jeśli spojrzysz na dokument użytkowania virtualenv , zauważysz, że mówi:

ENV/bintworzony jest tam, gdzie działają pliki wykonywalne - zauważalnie nowy python . W ten sposób uruchomienie skryptu #! /path/to/ENV/bin/pythonuruchomiłoby ten skrypt pod pythonem virtualenv.

Innymi słowy, zakładając, że crossbarskrypt Python, który chcesz uruchomić, wymaga venv-apvirtualenv, po prostu zacznij crossbarod:

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

I będzie automatycznie używać virtualenv przy każdym wywołaniu.

Możliwe jest również wywołanie interpretera Pythona bezpośrednio z virtualenv przy pomocy:

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

(Ponadto, jeśli chodzi o uruchamianie w określonym katalogu, ustawienie WorkingDirectory=/home/debian/apjest lepsze niż użycie cdpolecenia. Nie potrzebujesz w ten sposób powłoki, a systemd może zrobić lepszą obsługę błędów.)

filbranden
źródło