如何使用 systemd 在 vi​​rtualenv 中运行命令

ssc*_*rus 27 python systemd python3 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
Run Code Online (Sandbox Code Playgroud)

这些命令必须按此顺序执行。由于 virtualenv、不可执行的 crossbar 以及之后的单独 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
Run Code Online (Sandbox Code Playgroud)

fil*_*den 36

这不工作,因为source是一个shell命令,所以systemd的ExecStart=或者ExecStartPre=不会直接了解他们......(顺便说一句,同样是真实的cd&&。)

可以通过显式运行 shell 并在那里运行所有命令实现这一点:

ExecStart=/bin/sh -c 'cd /home/debian/ap/ && source venv-ap/bin/activate && crossbar start'
Run Code Online (Sandbox Code Playgroud)

但更好的方法是直接使用virtualenv 中的python可执行文件,而不是采购“激活”脚本bin/

如果您查看 virtualenv 的使用文档,您会注意到它说:

ENV/bin已创建,可执行文件所在的位置 - 显然是一个新的python。因此,运行脚本 with#! /path/to/ENV/bin/python将在此 virtualenv 的 python 下运行该脚本。

换句话说,假设crossbar您要运行的 Python 脚本需要venv-apvirtualenv,只需从以下内容开始crossbar

#!/home/debian/ap/venv-ap/bin/python
Run Code Online (Sandbox Code Playgroud)

每当调用时,它都会自动使用 virtualenv。

也可以直接从 virtualenv 调用 Python 解释器,使用:

ExecStart=/home/debian/ap/venv-ap/bin/python /path/to/crossbar start
Run Code Online (Sandbox Code Playgroud)

(另外,关于在特定目录中运行,设置WorkingDirectory=/home/debian/ap比使用cd命令更好。你不需要这样的shell,systemd可以为你做更好的错误处理。)