Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
systemd execstart python守护进程使用virtualenv from环境变量动态启动_Python_Virtualenv_Systemd - Fatal编程技术网

systemd execstart python守护进程使用virtualenv from环境变量动态启动

systemd execstart python守护进程使用virtualenv from环境变量动态启动,python,virtualenv,systemd,Python,Virtualenv,Systemd,我在CentOS 7中使用Python脚本作为systemd守护进程。守护进程由我在virtualenv中创建的python版本执行。我正在尝试调整脚本,以便能够在环境变量中设置virtualenv路径,以便通过一个变量更改路径并重新启动服务,轻松切换到不同的virtualenv。我已经创建了我的systemd脚本,以便能够初始化守护进程的多个实例,这非常有效。当我试图使用一个环境变量来指向我的python解析器时,情况就不一样了。这是我到目前为止所拥有的 /etc/系统D/系统/管道-remo

我在CentOS 7中使用Python脚本作为systemd守护进程。守护进程由我在virtualenv中创建的python版本执行。我正在尝试调整脚本,以便能够在环境变量中设置virtualenv路径,以便通过一个变量更改路径并重新启动服务,轻松切换到不同的virtualenv。我已经创建了我的systemd脚本,以便能够初始化守护进程的多个实例,这非常有效。当我试图使用一个环境变量来指向我的python解析器时,情况就不一样了。这是我到目前为止所拥有的

/etc/系统D/系统/管道-remove@.service:

[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/path/to/venv/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service
[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
EnvironmentFile=/etc/profile.d/pipeline_envvars.sh
ExecStart=/${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service
/etc/systemd/system/pipeline-remove.service(启动所有实例):

pipeline-remove-start.sh:

#!/bin/bash
systemctl start pipeline-remove@{1..2}
这对我来说非常有用,但当我尝试按以下方式设置python目录时,情况就不一样了:

/etc/profile.d/pipeline_envvars.sh:

PIPELINE_VIRTUALENV=/path/to/venv
/etc/系统D/系统/管道-remove@.service:

[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/path/to/venv/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service
[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
EnvironmentFile=/etc/profile.d/pipeline_envvars.sh
ExecStart=/${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service
然后我尝试启动它:

sudo systemctl daemon-reload
sudo systemctl restart pipeline-remove@{1..1}
sudo systemctl status pipeline-remove@{1..1}
状态显示以下退出代码203,表示未找到可执行文件:

● pipeline-remove@1.service - pipeline remove tickets worker instances as a service, instance 1
   Loaded: loaded (/etc/systemd/system/pipeline-remove@.service; disabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Fri 2018-01-26 15:04:50 UTC; 6s ago
  Process: 11716 ExecStart=/${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py (code=exited, status=203/EXEC)
 Main PID: 11716 (code=exited, status=203/EXEC)

Jan 26 15:04:50 dev systemd[1]: pipeline-remove@1.service: main process exited, code=exited, status=203/EXEC
Jan 26 15:04:50 dev systemd[1]: Unit pipeline-remove@1.service entered failed state.
Jan 26 15:04:50 dev systemd[1]: pipeline-remove@1.service failed.
找到了exec代码。在syslog,/var/log/messages中也可以找到:

Jan 26 15:07:13 dev systemd: Starting pipeline remove tickets worker instances as a service, instance 1...
Jan 26 15:07:13 dev systemd: Failed at step EXEC spawning /${PIPELINE_VIRTUALENV}/bin/python: No such file or directory
Jan 26 15:07:13 dev systemd: pipeline-remove@1.service: main process exited, code=exited, status=203/EXEC
Jan 26 15:07:13 dev systemd: Unit pipeline-remove@1.service entered failed state.
Jan 26 15:07:13 dev systemd: pipeline-remove@1.service failed.
Jan 26 15:07:23 dev systemd: pipeline-remove@1.service holdoff time over, scheduling restart.
Jan 26 15:07:23 dev systemd: Started pipeline remove tickets worker instances as a service, instance 1.
当我尝试在
ExecStart
中删除前导的
/
时,即使我的环境变量包含绝对路径,我也会得到一个相对路径错误:

Failed to start pipeline-remove@1.service: Unit is not loaded properly: 
Invalid argument.
See system logs and 'systemctl status pipeline-remove@1.service' for 
details.
状态显示如下:

vagrant@dev:~$ sudo systemctl status pipeline-remove@{1..1}
● pipeline-remove@1.service - pipeline remove tickets worker instances as a service, instance 1
   Loaded: error (Reason: Invalid argument)
   Active: inactive (dead)

Jan 26 15:11:39 dev systemd[1]: pipeline-remove@1.service failed.
Jan 26 15:11:42 dev systemd[1]: Stopped pipeline remove tickets worker instances as a service, instance 1.
Jan 26 15:11:42 dev systemd[1]: [/etc/systemd/system/pipeline-remove@.service:12] Executable path is not absolute, ignoring: ${PIPELINE_VIRTUALENV}/bin/python /pipel...e_tickets.py
Jan 26 15:11:42 dev systemd[1]: pipeline-remove@1.service lacks both ExecStart= and ExecStop= setting. Refusing.

我用指南来帮助我开始,但现在我被卡住了。如何在从环境变量设置python可执行路径时启动python守护进程?

在进一步阅读之后,我偶然发现了答案。问题是
ExecStart
的第一个参数必须是文本:

ExecStart=执行此操作时执行的命令及其参数 服务已启动。对于每个指定的命令,第一个 参数必须是可执行文件的绝对文本路径

进一步阅读ExecStart,它说:

在展开时其值未知的变量被视为 空字符串请注意,第一个参数(即 执行)可能不是变量

我最后也遇到了同样的问题。最后,这是有效的:用shell包装整个东西以运行:

[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
EnvironmentFile=/etc/profile.d/pipeline_envvars.sh
ExecStart=/bin/sh -c '${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py'
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service

因此
ExecStart=/bin/sh-c'
节省了时间,现在我可以为我的环境变量指定python解释器路径。我将保留答案,希望能为其他人节省一些时间。

再读几遍后,我无意中找到了答案。问题是
ExecStart
的第一个参数必须是文本:

ExecStart=执行此操作时执行的命令及其参数 服务已启动。对于每个指定的命令,第一个 参数必须是可执行文件的绝对文本路径

进一步阅读ExecStart,它说:

在展开时其值未知的变量被视为 空字符串请注意,第一个参数(即 执行)可能不是变量

我最后也遇到了同样的问题。最后,这是有效的:用shell包装整个东西以运行:

[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
EnvironmentFile=/etc/profile.d/pipeline_envvars.sh
ExecStart=/bin/sh -c '${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py'
Restart=always
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=pipeline-remove.service
因此
ExecStart=/bin/sh-c'
节省了时间,现在我可以为我的环境变量指定python解释器路径。将保留答案,希望能为其他人节省一些时间