Systemd:如何在 Virtualenv 中啟動/停止應該在後台執行的 Python 腳本
在我的 Raspbian 機器上,我希望與我的 VPN 提供商建立成功的 OpenVPN 連接以啟動 Python 腳本,只要 VPN 連接處於活動狀態,該腳本就應該在後台持續執行。如果/當 VPN 連接離線時,我想終止 Python 腳本。
我的想法是:OpenVPN 配置文件中的
up
anddown
標誌將執行啟動和停止systemd
服務的 shell 腳本。沒有它,Requires
該服務不能(不應該)執行。openvpn.service
使事情複雜化的是,我想
Virtualenv
在 bash 中可以通過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 腳本後進行適當的清理,在系統關閉/重啟時會發生什麼等?
你應該首先簡化你的別名,不需要做啟動的東西。重要的是 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 將嘗試停止/終止您的應用程序,您可以使用信號處理程序擷取