我相信这应该很简单,但我无法让它正常工作。
这些是我可以在命令行上运行的命令:
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、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
这不起作用,因为
source
它是一个 shell 命令,所以 systemdExecStart=
或者ExecStartPre=
不会直接理解它们......(顺便说一句,对于cd
和也是如此&&
。)您可以通过显式运行 shell 并在那里一起运行所有命令来实现这一点:
但更好的方法是直接使用 virtualenv
python
中的可执行文件,而不是采购“激活”脚本。bin/
如果您查看 virtualenv 的使用文档,您会注意到它说:
换句话说,假设
crossbar
您要运行的 Python 脚本需要venv-ap
virtualenv,只需从以下内容开始crossbar
:并且它会在调用时自动使用 virtualenv。
也可以直接从 virtualenv 调用 Python 解释器,方法是:
(另外,关于在特定目录中运行,设置
WorkingDirectory=/home/debian/ap
比使用cd
命令更好。你不需要这样的 shell,systemd 可以为你做更好的错误处理。)我想迭代@filbranden 的回答第二部分
不要在没有激活的情况下在 venv 中运行东西!公平地说,文档也具有误导性。激活 venv 使您能够将工作目录与 python(和 venv-ed 包)路径分开,这是经常必须的:您不想直接在 venv bin 中运行/放置某些东西,但是您安装了一些脚本对它的依赖。
考虑以下情况(我敢打赌这是最常见的情况之一):
如果你甚至想从 git repo 处理应用程序,你希望它的文件夹是原始的,除了你有意义的代码修改。你不会想改变shebang。您可以将整个 venv 放入克隆的 repo 中的子目录中并 gitignore 它以保持一切井井有条,但是:
另外,也许您不想直接运行 python,但是例如:gunicorn,并且您将 webapp 放置在
/srv
venv 位于/var/lib
.不激活 venv 不是一个好习惯,我想知道那个愚蠢的段落是如何进入官方 venv 文档的。是的,在某些情况下不需要激活它,除非在很多真实场景中!- 我认为。
ExecStartPre
无论如何都不适用于采购 venv,因为它是在与ExecStart
命令不同的 shell 中执行的,因此环境变量在后者中不会正确。我建议设置 venv PATH
Environment