起こったエラー
Synology の DS118 内にあるPythonのスクリプトを、DSM のタスクスケジューラーから実行しようとしたところ、モジュールのインポートエラーが起きました。
Traceback (most recent call last):
File "hoge.py", line 1, in <module>
import tweepy
ModuleNotFoundError: No module named 'tweepy'
おかしいぞ?
SSH接続ではできるのに。。
しかもこれ、以前requests
でも同様のエラーに遭ってしまいましたが、その時はそれほどタスクスケジューラーでやる必要性がなかったことから、放置していました。
ですが今回はタスクスケジューラーでやる必要があったので、本腰を入れて対処してみることに。
分からないなりに調べると、パスが通ってない感じに思え。
おそらく、SSHで実行するのとタスクスケジューラーで実行するのと、微妙に異なるのでしょう。
というわけで、以下の通り対処してみました。
なお、pythonはパッケージセンターからインストールしてあってバージョンは3.8.2
、SDKのバージョンはDSM 6.2.3-25426 Update 3
です。
パスの確認
SSH接続とタスクスケジューラーの各々から、以下のコードを実行してパスのリストに差があるか確認します。
import sys
path_list = sys.path
with open('/your_storage/your_directory/check_module_path.txt', 'w', encoding='utf-8') as f:
for path in path_list:
f.write(path + '\n')
SSH接続から実行した場合
/my_storage/my_directory
/var/packages/py3k/target/usr/local/lib/python38.zip
/var/packages/py3k/target/usr/local/lib/python3.8
/var/packages/py3k/target/usr/local/lib/python3.8/lib-dynload
/var/services/homes/synology_user_name/.local/lib/python3.8/site-packages
/var/packages/py3k/target/usr/local/lib/python3.8/site-packages
/usr/lib/python3/site-packages
タスクスケジューラーから実行した場合
/my_storage/my_directory
/var/packages/py3k/target/usr/local/lib/python38.zip
/var/packages/py3k/target/usr/local/lib/python3.8
/var/packages/py3k/target/usr/local/lib/python3.8/lib-dynload
/var/packages/py3k/target/usr/local/lib/python3.8/site-packages
/usr/lib/python3/site-packages
う~~ん、、/var/services/homes/synology_user_name/.local/lib/python3.8/site-packages
が、SSH接続にはあってタスクスケジューラーにはないですね。
ここにtweepy
やrequests
のモジュールがいそうですので、SSH接続からこのディレクトリ内をls -l
で確認してみます。
ls -l /var/services/homes/synology_user_name/.local/lib/python3.8/site-packages
# 略(多数)
# drwxrwxrwx+ 3 synology_user_name users 4096 Jan 14 05:57 tweepy
# 略(多数)
tweepy
ありました!
もちろん、requests
もありました!
対処方法
対処方法は、二つあります。
一つ目は、スクリプト内に2行ほどコードを加える方法で、こちらの方が簡単。
もちろん私は、迷ったら簡単な方を選ぶ怠惰なやつです。。
二つ目は、タスクスケジューラーからデフォルトのパスを通す方法。
おそらくこちらで対処すべきなんでしょうけど、私のレベルではやり方が分からず。。
でも、とりあえず書くだけ書いておきます。
スクリプト内で対処する方法
以下のコードを、モジュールのimport文の前に記述します。
import sys
sys.path.append('/var/services/homes/synology_user_name/.local/lib/python3.8/site-packages')
これだけで、エラー回避ができます!
分かると簡単なのですが、分かるまでが大変ですよね、こいういうのって。
タスクスケジューラーからデフォルトのパスを通す方法
パスを通すには、~/.bashrc
からvi
等のエディタで以下を追記すればいいのかもなのですが、これをタスクスケジューラー上でやるのってどうすればいいのか分からず。。
export PATH=$PATH:"/var/services/homes/synology_user_name/.local/lib/python3.8/site-packages"
タスクスケジューラーのスクリプトの中で、vi
ってできるんですかね??
ご存じの方いらっしゃいましたら、ご教示いただけますとありがたいですm(_ _)m
##参考
[Pythonでimportの対象ディレクトリのパスを確認・追加(sys.pathなど) | note.nkmk.me](https://note.nkmk.me/python-import-module-search-path/"Pythonでimportの対象ディレクトリのパスを確認・追加(sys.pathなど) | note.nkmk.me")
[【Python環境構築】環境変数について解説! | WEBCAMP NAVI](https://web-camp.io/magazine/archives/19240#Python-2"【Python環境構築】環境変数について解説! | WEBCAMP NAVI")
[pythonのパッケージの保存場所 - Qiita](https://qiita.com/ophhdn/items/4d3ecc6354d92b7ac0ba"pythonのパッケージの保存場所 - Qiita")
[Python内のデフォルトパスを通す方法(Windows, Linux) - Qiita](https://qiita.com/maech/items/72559402556eb2af73ad"Python内のデフォルトパスを通す方法(Windows, Linux) - Qiita")