我有一个 Flask 应用程序,其中app.py
包含以下文件flask_apscheduler
:
from flask_apscheduler import APScheduler
app = Flask(__name__)
scheduler = APScheduler()
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres@localhost/mydb'
db = SQLAlchemy(app)
#my sqlAlchemy models:
class RiskCountry(db.Model):
id = ...
@app.route('/')
def dataToDb():
#scrape data from website and update database
...
if __name__ == '__main__':
scheduler.add_job(id = 'test', func = dataToDb, trigger = 'interval', minutes = 60)
scheduler.start()
app.run()
现在我想使用 将此脚本作为服务运行systemd
。我在 中创建了以下myservice.service
文件/etc/systemd/system
:
[Unit]
Description=scraping data and push to DB
After=network.target network-online.target
Requires=network-online.target
[Service]
ExecStart="/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py"
Restart=always
WorkingDirectory=/home/geolic/my-app
User=root
Group=root
[Install]
WantedBy=multi-user.target
现在我去了我的控制台并做了
$ systemctl enable myservice
$ systemctl daemon-reload
$ systemctl start myservice
$ systemctl status myservice -l
但是,我的服务运行失败并显示错误消息:
已加载:已加载(/etc/systemd/system/myservice.service;已启用;供应商预设:已禁用)
活动:失败(结果:启动限制)自 2020-08-19 星期三 07:50:57 CEST 起;6 秒前进程:21863
ExecStart=/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py(代码=exited,状态=203/EXEC)
主 PID:21863(代码=exited,状态=203/EXEC)
日志告诉我systemd
无法找到我使用的文件ExecStart
。但是,当我在控制台中运行该语句时,它可以正常工作...
我在这里做错了什么?
答案1
这是因为你试图传递整个命令行作为一条很长的路径,而它应该由两条独立的路径组成。
systemd 的 ExecStart 中指定的值是不是传递给 shell 以解释为命令。相反,该选项直接采用空格分隔的单词列表(可执行文件及其参数)。因此正确的设置应该是:
ExecStart="/home/geolic/my-app/env/bin/python" "/home/geolic/my-app/app.py"
ExecStart=/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py
将此与在实际 shell 中引用整个命令行时发生的情况进行比较:
$ head -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
$ "head -1 /etc/passwd"
bash: head -1 /etc/passwd: No such file or directory