LoginSignup
2
0

More than 3 years have passed since last update.

Synology DSMのタスクスケジューラーでpython実行時に起こるインポートエラーの回避方法

Last updated at Posted at 2021-01-16

起こったエラー

Synology の DS118 内にあるPythonのスクリプトを、DSM のタスクスケジューラーから実行しようとしたところ、モジュールのインポートエラーが起きました。

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接続とタスクスケジューラーの各々から、以下のコードを実行してパスのリストに差があるか確認します。

check_module_path.py
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接続から実行した場合

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接続にはあってタスクスケジューラーにはないですね。
ここにtweepyrequestsのモジュールがいそうですので、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文の前に記述!
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
【Python環境構築】環境変数について解説! | WEBCAMP NAVI
pythonのパッケージの保存場所 - Qiita
Python内のデフォルトパスを通す方法(Windows, Linux) - Qiita

2
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0