Pythonで実行時のディレクトリを作成&自動実行

スポンサーリンク

時には日付でディレクトリを作成して、処理結果やら取得データやらを入れて置きたい事があります。
実は、今まで手動でディレクトリを切って、手動でコマンドを実行していたのですが、それを自動でやってくれるようにしました。
言語は何でも良いのですけど、元々の処理がPythonで作っていたので、Pythonでのお話です。

スポンサーリンク

日付の文字列を取得する

まずは、実行時の日付を取得する必要があるので、その部分です。

import datetime

today = datetime.datetime.today()

単純にdatetimeのtoday()で取得できるので、これはすんなりいきますね。
次は、ディレクトリ名"240623″の形の文字列の作成です。
0埋め2桁の数字を年、月、日の順につなげているだけの良くあるフォーマットです。
始めに考えたのは下のコード(Pythonはほぼ初心者なので、文字列フォーマットの方法を調べました)

dir_name = "{0:02d}{1:02d}{2:02d}".format(today.year % 100, today.month, today.day)

datetime型から年、月、日を取り出して、文字列のフォーマットを自力で使う形です。
これでも何も問題は無いですけど少し泥臭いですね……恐らく、日付を扱うライブラリにはもっと便利なメソッドがあるはず……
と言う事で少し調べたら出てきました。(strftime()とstrptime()の振る舞い

dir_name = today.strftime("%y%m%d")

どの言語でも存在する、日付を扱うライブラリでの日付フォーマットを指定する方法です。
まぁ、こっちを採用ですね😄

ディレクトリを作成する

次はディレクトリを作成する部分です。
これも少し調べれば情報が出てきました。

import os

os.mkdir(dir_name)

まぁ、これで作成することはできるのですけど……既に存在している場合も考えて置きたいです。
そこで、ディレクトリが既に存在しているかどうかの判定を追加してみました。

if os.path.isdir(dir_name):
  print("既にディレクトリが存在 : " + dir_name)
  # 処理を止めたいならここで exit(-1) とかして終了させる
else:
  print("新規にディレクトリ作成 : " + dir_name)
  os.mkdir(dir_name)

これで、ディレクトリが無ければ作成する(既にあったら何もしない)と言う処理ができました。
ただ、これをもっと簡単に書ける記述もあります。

os.makedirs(dir_name, exist_ok = True)

“ディレクトリが無ければ作成。既にあったら何もしない" がこれだけで完結します。
exist_od = Trueが既に存在していてもエラーにしないと言う動きの指定のようです。
(makedirsは再起的ディレクトリ作成の機能があるけど、今回のテーマから外れちゃうので割愛します)
ただ、今回は存在してた場合にログを出したいので、前者を採用します。

ディレクトリ移動

最後に作業を作成したディレクトリで行うために、ディレクトリ移動をします。
これをしないと、折角ディレクトリを作成した意味がなくなってしまいます。(実は、テストした時にやってしまいました💦)

os.chdir(dir_name)

mkdirと同じく、コマンドラインで作業する人には馴染みのあるメソッド名chdirです。
これでやりたいコードは全部できました。👍

最終コード

最後に今回のコードをまとめます

import datetime

# 何処で実行しても大丈夫なようにルートディレクトリに移動させちゃう
os.chdir("/home/developer")

today = datetime.datetime.today()
dir_name = today.strftime("%y%m%d")
if os.path.isdir(dir_name):
  print("既にディレクトリが存在 : " + dir_name)
  # 処理を止めたいならここで exit(-1) とかして終了させる
else:
  print("新規にディレクトリ作成 : " + dir_name)
  os.mkdir(dir_name)
os.chdir(dir_name)

# ###################################
# ここに作成したディレクトリ内での処理を書く
# ###################################

それなりに色々書きましたけど、たったこれだけで完了です。
多分、ChatGPTとかに聞けば、すぐに答えてくれるレベルですね。

自動実行 cron

簡単に定時で自動実行されるならcronで設定するのが手っ取り早いですね。
今回は、平日の16:15になったら処理を走らせたいので、以下のように設定しました。

15 16 * * 1-5 python3 /home/developer/command.py > /home/developer/log/command.log 2>&1

実行ファイル名が command.py です。
そして、明確にログを出すように、ログの出力先も指定しています。

(cronって何?どうやって設定するの? などは本題から外れてしまうので、自分で調べて下さいませ)

これで、今回やりたいことは完了です。🎉

(おまけ)前日の日付でディレクトリを作る

実は、翌朝に前日の日付で処理をしたい事もあるので、それもおまけで載せて置きます。

import datetime

# 何処で実行しても大丈夫なようにルートディレクトリに移動させちゃう
os.chdir("/home/developer")

yesterday = datetime.datetime.today() - datetime.timedelta(days=1)
dir_name = yesterday.strftime("%y%m%d")
if os.path.isdir(dir_name):
  print("既にディレクトリが存在 : " + dir_name)
else:
  print("新規にディレクトリ作成 : " + dir_name)
  # 処理を止めたいならここで exit(-1) とかして終了させる
  os.mkdir(dir_name)
os.chdir(dir_name)

# ###################################
# ここに作成したディレクトリ内での処理を書く
# ###################################

日付を取得している所で、- datetime.timedelta(days=1) をして1日減らしているだけです。
あとは、こっちは前日の処理でディレクトリが存在しているのが通常なので、少しif文のコメント位置が変わっています。

ちなみに、cronの設定はこう

15 7 * * 2-6 python3 /home/developer/command2.py > /home/developer/log/command2.log 2>&1

実行曜日も1日ずらして、火曜〜土曜の7:15となります。

まとめ

少し調べれば出てくる情報ではありますが、自分の備忘録な意味も込めて記事にしてみました。
実際に私が作成したスクリプトには、処理の開始と完了時にSlack通知するコードも書いたけど、Slack通知は事前準備とかあって記事にするには一手間あるので、今回は除外しています。
これで、ずっとやりたいと思っていた事が一つ片付いた〜 ヽ(´▽`)/ バンザーイ

今後もこんな仕様もない事を記事にして、更新頻度を上げていきたいな〜と思います。

スポンサーリンク