LoginSignup
8
8

More than 5 years have passed since last update.

【Python】crontabで、ファイルを読み込むスクリプトを動かす時にpathlibを使うと楽だった

Last updated at Posted at 2018-07-01

crontabで設定ファイルが読み込まれない

普段はpythonで仮想通貨の自動取引Botを作ったりしているのですが、息抜きに全く関係ない大学用のTwitterBotを作りました。

KU休講情報Bot

このBotは講義が終わるたびにその日の休講情報を呟くものです。
これをcrontabで定期実行させようと考えました。

しかし、設定をしても同じディレクトリにあるアクセストークン等が書かれたjsonファイルが読み込まれない。おかしいと思いログをあさってみると、No such file or directory

調べてみるとcrontabのカレントディレクトリがホームディレクトリにあることが原因でした。

解決法

先に解決法を書いておきます。以下のようにコードを変更しました。

  • 変更前
f = open("./hoge.json","r") #相対パスでは読み込まれずエラーが起きる
  • 変更後
from pathlib import Path
path = Path.cwd() / Path(__file__).parents[0] / "hoge.json"
f = open(path,"r")

原因

crontabのカレントディレクトリはホームディレクトリ

crontabのカレントディレクトリはホームディレクトリであり、スクリプトがあるディレクトリではありません。よって、./hoge.jsonのように書くとファイルが読み込まれません。

なぜpathlibを使うのか

異なる環境でも動作する

相対パスでエラーが起きてしまう場合、絶対パスでファイルを参照したりしますが、それだと別の環境下(WindowsとLinuxなど)で使えません。引数でファイルパスを設定するのもありですが、毎回するのは面倒くさいです。

そんな時にpathlibは効果を発揮します。pathlibはPython3.4で追加された公式のモジュールです。

pathlibはパスを表すクラスを提供し、パス通しの連結を/で行います。

from pathlib import Path
hoge = Path("hoge")
fuga = Path("fuga.py")
print(hoge / fuga)

# > hoge/fuga.py (Linux)
# > hoge\fuga.py(Windows)

パス通しの連結の際に自動的にOSに準拠した表記になり、異なる環境でも動作します。

上位パスにアクセスしやすい

pathlibは上位パスをparents[n]で取得できます。

from pathlib import Path
path = Path("aaa/bbb/ccc/ddd")
print(path)
print(path.parents[0])
print(path.parents[1])

# > aaa/bbb/ccc/ddd
# > aaa/bbb/ccc
# > aaa/bbb

open()の引数に使える

pythonでファイルを読み込む場合、大抵open()が使われますが、この引数にPath()を使うことができます。(Pytho3.6から)

後は目的のディレクトリまでパスをつなげるだけ

これらを用いれば先に書いたようにパスを指定できます。

path = Path.cwd() / Path(__file__).parents[0] / "hoge.json"

Path.cwd()はカレントディレクトリを返すクラスメソッドです。
また__file__はスクリプトの絶対パスを表します。よって、スクリプトと同じ階層にあるファイルを読み込む場合は、Path(__file__).parents[0]と一つ上の階層のパスを用います。

参考

  1. 11.1. pathlib — オブジェクト指向のファイルシステムパス
  2. Python3.4以降ならos.pathはさっさと捨ててpathlibを使うべき
  3. cronの設定方法
8
8
0

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
8
8