systemd를 사용하여 virtualenv에서 명령을 실행하는 방법

systemd를 사용하여 virtualenv에서 명령을 실행하는 방법

나는 이것이 간단해야 한다고 생각하지만 그것을 작동시킬 수는 없습니다.

명령줄에서 실행할 수 있는 명령은 다음과 같습니다.

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

이러한 명령은 이 순서대로 실행되어야 합니다. virtualenv, 크로스바 및 별도의 Python 스크립트를 실행할 수 없기 때문에 이를 작동시키는 최선의 방법을 찾을 수 없습니다. 현재 하고 있는 일:

[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

답변1

source이것은 쉘 명령이기 때문에 작동하지 않으므로 systemd ExecStart=or ExecStartPre=not은 직접 이해할 것입니다 ... (BTW, cd및 에도 동일합니다 &&.)

할 수 있다셸을 명시적으로 실행하고 거기에서 모든 명령을 함께 실행하여 이를 수행합니다.

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

python그러나 더 좋은 방법은 "활성화" 스크립트를 얻는 대신 virtualenv에서 직접 실행 파일을 사용하는 것입니다 .bin/

virtualenv를 보면파일 작업, 다음과 같은 내용이 표시됩니다.

ENV/bin실행 파일이 있는 곳에 생성됩니다. 분명히 새로운 실행 파일입니다.파이썬. 따라서 스크립트를 실행하면 #! /path/to/ENV/bin/python해당 virtualenv의 Python에서 스크립트가 실행됩니다.

즉, crossbar실행하려는 Python 스크립트에 virtualenv가 필요하다고 가정하면 venv-ap다음 crossbar과 같이 시작하세요.

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

호출될 때마다 자동으로 virtualenv를 사용합니다.

다음을 수행하여 virtualenv에서 직접 Python 인터프리터를 호출할 수도 있습니다.

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

(또한 특정 디렉터리에서 실행하는 경우 명령을 WorkingDirectory=/home/debian/ap사용하는 것보다 설정하는 것이 좋습니다 cd. 이렇게 하면 쉘이 필요하지 않으며 systemd가 더 나은 오류 처리를 수행할 수 있습니다.)

답변2

@filbranden 답변의 두 번째 부분을 반복하고 싶습니다.

그러나 더 나은 접근 방식은 "활성화" 스크립트를 얻는 대신 virtualenv의 bin/에서 직접 Python 실행 파일을 사용하는 것입니다.

virtualenv의 사용 문서를 보면 다음과 같은 내용이 있음을 알 수 있습니다.

ENV/bin이 생성되고 실행 파일이 여기에 상주합니다. 분명히 새로운 Python입니다. 따라서 #! /path/to/ENV/bin/python을 사용하여 스크립트를 실행하면 이 virtualenv의 Python에서 스크립트가 실행됩니다.

venv를 활성화하지 않고 실행하지 마세요! 공정하게 말하면 문서그것은 또한 오해의 소지가 있습니다. venv를 활성화하면 Python(및 venv-ed 패키지) 경로에서 작업 디렉터리를 분리할 수 있습니다.필수일반적으로 venv bin에서 직접 무언가를 실행/배치하고 싶지 않지만 일부 스크립트의 종속성이 설치되어 있습니다.

다음 시나리오를 고려해보세요(가장 일반적인 시나리오 중 하나일 것입니다).

  • git 저장소에서 스크립트를 실행해야 하지만 해당 종속성이 Python 패키지와 호환되지 않습니다.
  • virtualenv를 생성하고 pip가 종속성을 설치했습니다.
  • 저장소를 어딘가에 복제했지만 스크립트가 Venv의 저장소에 없습니다.

git 리포지토리에서 애플리케이션 작업을 하고 싶다면 의미 있는 코드 수정을 제외하고 해당 폴더가 원래 상태로 유지되기를 원할 것입니다. 당신은 shebang을 바꾸고 싶지 않습니다. 전체 Venv를 복제된 저장소의 하위 디렉터리에 넣고 gitignore하여 모든 것을 정리할 수 있지만 다음과 같은 작업을 수행할 수 있습니다.

  • systemd 작업 디렉터리를 복제된 폴더로 설정할 수 있습니다.
  • 하위 폴더에 대한 Python 전체 경로를 사용하여 스크립트를 실행합니다.
  • 스크립트는 pip-ed deps가 작업 폴더나 경로에 없기 때문에 찾지 않습니다. 폴더 계층 구조를 바꾸면(저장소를 venv의 하위 폴더로 복제) 문제가 지속됩니다.

또한 Python을 직접 실행하고 싶지 않을 수도 있지만 예를 들어 gunicorn이 /srv있고 /var/lib.

venv를 활성화하지 않는 것은 좋은 습관이 아닙니다., 이 바보 같은 문단이 어떻게 공식 venv 문서에 포함되었는지 궁금합니다. 예, 어떤 경우에는 활성화할 필요가 없습니다.많은 실제 시나리오를 제외하고!- 제 생각에는.

ExecStartPre어쨌든 ExecStart명령과 다른 쉘에서 실행되기 때문에 venv 소싱에는 작동하지 않으므로 후자에서는 환경 변수가 올바르지 않습니다.

venv PATH를 설정하는 것이 좋습니다.Environment

관련 정보