Debian

Systemd:如何在 Virtualenv 中啟動/停止應該在後台執行的 Python 腳本

  • November 1, 2018

在我的 Raspbian 機器上,我希望與我的 VPN 提供商建立成功的 OpenVPN 連接以啟動 Python 腳本,只要 VPN 連接處於活動狀態,該腳本就應該在後台持續執行。如果/當 VPN 連接離線時,我想終止 Python 腳本。

我的想法是:OpenVPN 配置文件中的upanddown標誌將執行啟動和停止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腳本,該腳本又執行.pyPython 腳本。

示意圖:

OpenVPN upovpn_up.shsudo systemctl start vpn_up.serviceExecStart=/path/to/start_pythonscript.shcoding; python my_script.py

OpenVPN downovpn_down.shsudo 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,第二次呼叫知道如何通知started 應用程序並優雅地關閉。如果您沒有ExecStopsystemd,IIRC 將嘗試停止/終止您的應用程序,您可以使用信號處理程序擷取

引用自:https://unix.stackexchange.com/questions/278188