![systemd を使用して Python スクリプトをデーモン化できません - 「oandapyV20」という名前のモジュールがありません](https://rvso.com/image/170267/systemd%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%20Python%20%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3%E5%8C%96%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%20-%20%E3%80%8CoandapyV20%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E5%90%8D%E5%89%8D%E3%81%AE%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93.png)
systemd を使用して Python スクリプトをデーモン化しようとしていますが、デーモンをアクティブ化した後に「'oandapyV20' という名前のモジュールがありません」というエラーが頻繁に発生します。
スクリプトは次の場所にあります: /home/user/workingdir/script.py
仮想環境は次の場所にあります: /home/user/venv/bin/
私が見つけたドキュメントからサービスを構築する方法についての私の推測は次のとおりです。
[Unit]
Description=DataLoader
[Service]
User=root
Group=root
WorkingDirectory=/home/user/workingdir
ExecStart=/home/user/venv/bin/python3 script.py
[Install]
WantedBy=multi-user.target
何が機能するのか...
python3 スクリプト.py
または仮想環境をアクティブ化する
ソース /home/user/venv/bin/activate; python3 script.py
これはサービス外では機能しますが、systemd から呼び出す場合は試したものは何も機能しません。
どこが間違っているのでしょうか? 何に気づいていないのでしょうか?
最終的な解決策(ほとんど理解されていない)
[Unit]
Description=DataLoader
[Service]
User={user_name}
Group={user_name}
WorkingDirectory=/home/{user_name}/workingdir
ExecStart=/usr/bin/python3 script.py
Restart=always
[Install]
WantedBy=multi-user.target
答え1
source /home/user/venv/activate
を呼び出すたびに、python3
コマンド (およびpip3
コマンド) がその後 から関連する実行可能ファイルを呼び出すという前提で操作していたようです/home/user/venv/bin
。
ただし、コメントで追加した説明によると、その仮定は間違っていました。 を実行しているときに仮想環境から Python を呼び出していなかったのです。script.py
で Python を呼び出していました/usr/bin
(仮想環境の Python にはモジュールがインストールされていないようですが、システムの Python にはインストールされているため、対応するものpip
も呼び出されているようですoandapyV20
)。
出力を調べる
echo $PATH
echo $PYTHONPATH
環境$PATH
変数は、コマンドを入力したときに検索されるシステム上のパスのコロンで区切られたリストです。 は/home/user/venv/bin
そのリストに存在しないか、 の出現後に出現します/usr/bin
。 には の一致が含まれますpython3
($PATH
最初の一致以降はスキャンが停止します)。は$PATH
通常 によって設定されます$HOME/.bashrc
(または、/etc/bashrc
そこで設定されていない場合は によって設定されます)。想定が正しければ、がその前に追加されるよう/home/user/venv/activate
設定されていたはずです。$PATH
/home/user/venv/bin
$PYTHONPATH
ロードするモジュールを探す場所を Python に指示する必要があります。(また、 を使用してスクリプトから変更したり読み取ったりすることもできますsys.path
。)
これが、systemd ユニットのコマンドを変更すると機能する理由です。最終的には、動作中のコマンドと同じ Python が呼び出されます。