在我的 Raspbian 计算机上,我希望与我的 VPN 提供商建立成功的 OpenVPN 连接以启动 Python 脚本,只要 VPN 连接处于活动状态,该脚本就应该在后台持续运行。如果/当 VPN 连接离线时,我想终止 Python 脚本。
我的想法是这样的:OpenVPN配置文件中的up
和标志将执行启动和停止服务的shell脚本。该服务和down
systemd
Requires
openvpn.service
不能 (不应该)没有它就运行。
让事情变得复杂的是我想Virtualenv
在 bash 中运行 Python 脚本,该脚本可以通过alias coding="cd /home/p1/Coding/Python/Virtual/py279/bin; source activate; cd /home/p1/Coding/Python/Projects"
. Python 文件的位置位于后一个文件夹中。
但是,据我了解,systemd
不能以上述方式运行命令行alias coding
。
所以我想一个解决方案可以用于systemd
执行一个.service
执行脚本的.sh
脚本,该脚本又执行.py
Python脚本。
示意图:
OpenVPN
up
→ovpn_up.sh
→sudo systemctl start vpn_up.service
→ExecStart=/path/to/start_pythonscript.sh
→coding; python my_script.py
OpenVPN
down
→ovpn_down.sh
→sudo systemctl stop vpn_up.service
我的假设是,这有一些警告和/或问题,特别是关于如何正确终止 Python 脚本。
问题:
- 这可行吗?
- 需要服务文件中的哪些部分和服务命令才能使其工作?
- 对于这种整体安排是否有任何特殊的考虑,例如终止Python脚本后的适当清理,系统关闭/重新启动时会发生什么等?
答案1
你应该首先简化你的别名,没有必要做激活的事情。重要的是 python 脚本的第一行 shebang 。它应该是:
#!/path/to/your/virtualenv/bin/python
如果脚本是可执行的 ( chmod +x script_name
),则上面的行确保调用 virtualenv 中安装的 python,并确保获取 virtualenv 中安装的包。
您可以为脚本创建一个别名,或者将脚本放在 PATH 中的某个目录中。
在 systemd 服务文件中,您应该使用脚本的完整路径。这样的脚本可能如下所示:
[Unit]
Description=your program description
Requires=any services that need to be installed
After=run after this service
[Service]
Restart=always
ExecStart=/root/bin/application start
ExecStop=/root/bin/application stop
[Install]
WantedBy=multi-user.target
上面假设你的 python 脚本已经存在,/root/bin/application
并且如果传入start
命令行参数,它就会启动,并且当使用 调用它时stop
,第二次调用不知何故知道如何通知start
ed 应用程序并正常关闭。如果你没有ExecStop
systemd,IIRC 会尝试停止/终止你的应用程序,你可以使用信号处理程序