0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

祝日データの自動ダウンロードと更新をシェルスクリプトで実現する方法

Last updated at Posted at 2024-10-14

はじめに

シェルスクリプトは、UnixやLinux環境でよく利用されるスクリプト言語で、コマンドの自動化やシステムの管理に役立ちます。

このスクリプトでは、祝日データの取得から更新までを自動化し、定期的なメンテナンスを効率化します。

具体的には、データのバックアップ、ダウンロード、変換、検証、更新の一連の処理を行います。

ログを用いて各処理の結果を記録することで、トラブルシューティングも容易にしています。

シェルスクリプトのフロー処理

ここでは、祝日データの自動化スクリプトの全体の流れをフローチャート形式で説明します。

1. 開始
   |
   V
2. 環境変数をセット
   - SYUKUJITSU_FILE
   - BACKUP_FILE
   - NEW_FILE
   - LOG_FILE
   - DOWNLOAD_URL
   |
   V
3. ログファイルをクリア
   |
   V
4. バックアップファイルを作成
   |-- 成功: "SUCCESS: バックアップを作成しました。" をログに書き込む
   |-- 失敗: "ERROR: バックアップの作成に失敗しました。" をログに書き込み、exit 1
   |
   V
5. 新しい祝日CSVファイルを取得
   |-- 成功: "SUCCESS: 新しい祝日CSVファイルを取得しました。" をログに書き込む
   |-- 失敗: "ERROR: 祝日CSVファイルの取得に失敗しました。" をログに書き込み、exit 1
   |
   V
6. 文字コードをSJISからUTF-8に変換
   |-- 成功: "SUCCESS: 文字コードの変換に成功しました。" をログに書き込む
   |-- 失敗: "ERROR: 文字コードの変換に失敗しました。" をログに書き込み、exit 1
   |
   V
7. ファイルサイズの検証
   |-- 成功: "SUCCESS: ファイルサイズの検証に成功しました。" をログに書き込む
   |-- 失敗: "ERROR: ファイルサイズが小さくなっています。" をログに書き込み、exit 1
   |
   V
8. バックアップファイルを削除
   |-- 成功: "SUCCESS: バックアップファイルを削除しました。" をログに書き込む
   |-- 失敗: "ERROR: バックアップファイルの削除に失敗しました。" をログに書き込み、exit 1
   |
   V
9. 新しいファイルをsyukujitsu.csvにリネーム
   |-- 成功: "SUCCESS: ファイルのリネームに成功しました。" をログに書き込む
   |-- 失敗: "ERROR: ファイルのリネームに失敗しました。" をログに書き込み、exit 1
   |
   V
10. "SUCCESS: 処理が完了しました。" をログに書き込み、終了

完成した全体コード

以下は、シェルスクリプト全体のコードです。祝日データの取得から更新までを自動化するための一連の処理を含んでいます。

コードの各部分については後述する解説で詳しく説明します。

syukujitsu.sh
#!/bin/bash

# 環境変数をセット
SYUKUJITSU_FILE="/home/honda/syukujitsu/syukujitsu.csv"
BACKUP_FILE="/home/honda/syukujitsu/backup_syukujitsu.csv"
NEW_FILE="/home/honda/syukujitsu/new_syukujitsu.csv"
LOG_FILE="/home/honda/syukujitsu/syukujitsu.log"
DOWNLOAD_URL="https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv"

# ログファイルをクリア
> "${LOG_FILE}"

# 今ある祝日のCSVファイルをコピーする(バックアップファイルを作成する)
if cp "${SYUKUJITSU_FILE}" "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: バックアップを作成しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: バックアップの作成に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

# CSVファイルを取得する
if curl -o "${NEW_FILE}" "${DOWNLOAD_URL}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 新しい祝日CSVファイルを取得しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: 祝日CSVファイルの取得に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

# 文字コードをSJISからUTF-8に変換する
if iconv -f SHIFT_JIS -t UTF-8 "${NEW_FILE}" > "${NEW_FILE}.utf8"; then
    mv "${NEW_FILE}.utf8" "${NEW_FILE}"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 文字コードの変換に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: 文字コードの変換に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

# 新しいCSVファイルとバックアップファイルのサイズを比較
if [ "$(stat -c%s "${NEW_FILE}")" -ge "$(stat -c%s "${BACKUP_FILE}")" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: ファイルサイズの検証に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: ファイルサイズが小さくなっています。" >> "${LOG_FILE}"
    exit 1
fi

# バックアップファイルを削除
if rm "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: バックアップファイルを削除しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

# 新しいファイルをsyukujitsu.csvにリネーム
if mv "${NEW_FILE}" "${SYUKUJITSU_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: ファイルのリネームに成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: ファイルのリネームに失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 処理が完了しました。" >> "${LOG_FILE}"
exit 0

事前に文字コードを変換した(UTF-8版)国民の祝日ファイルを同じディレクトリに配置しておく必要があります。

https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv

以下のようなディレクトリ構成になっています。

[honda@HONDA-TEST ~]$ tree syukujitsu
syukujitsu
├── syukujitsu.csv
└── syukujitsu.sh

ログファイルの出力結果

[honda@HONDA-TEST syukujitsu]$ ./syukujitsu.sh 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 20831  100 20831    0     0   5849      0  0:00:03  0:00:03 --:--:--  5871
[honda@HONDA-TEST syukujitsu]$ cat syukujitsu.log 
2024-10-14 21:39:53 - SUCCESS: バックアップを作成しました。
2024-10-14 21:39:57 - SUCCESS: 新しい祝日CSVファイルを取得しました。
2024-10-14 21:39:57 - SUCCESS: 文字コードの変換に成功しました。
2024-10-14 21:39:57 - SUCCESS: ファイルサイズの検証に成功しました。
2024-10-14 21:39:57 - SUCCESS: バックアップファイルを削除しました。
2024-10-14 21:39:57 - SUCCESS: ファイルのリネームに成功しました。
2024-10-14 21:39:57 - SUCCESS: 処理が完了しました。
[honda@HONDA-TEST syukujitsu]$ 

想定通りの出力結果になっていることが確認できました!

コードの部品解説

1. 環境変数をセット

SYUKUJITSU_FILE="/home/honda/syukujitsu/syukujitsu.csv"
BACKUP_FILE="/home/honda/syukujitsu/backup_syukujitsu.csv"
NEW_FILE="/home/honda/syukujitsu/new_syukujitsu.csv"
LOG_FILE="/home/honda/syukujitsu/syukujitsu.log"
DOWNLOAD_URL="https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv"

各種ファイルやURLのパスを環境変数としてセットします。

SYUKUJITSU_FILE: 現在使用中の祝日CSVファイルのパス。
BACKUP_FILE: バックアップ用のファイルパス。
NEW_FILE: ダウンロードした新しいCSVファイルのパス。
LOG_FILE: ログを記録するファイルのパス。
DOWNLOAD_URL: 祝日データのダウンロード先URL。

2. ログファイルをクリア

> "${LOG_FILE}"

LOG_FILEの内容をクリアし、新たにログを記録できるようにします。

3. バックアップファイルを作成

if cp "${SYUKUJITSU_FILE}" "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: バックアップを作成しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: バックアップの作成に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

現在の祝日CSVファイルをバックアップファイルとしてコピーします。
成功時にはログにSUCCESSとして記録し、失敗時にはERRORを記録してスクリプトを終了します。

4. CSVファイルを取得

if curl -o "${NEW_FILE}" "${DOWNLOAD_URL}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 新しい祝日CSVファイルを取得しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: 祝日CSVファイルの取得に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

curlコマンドを使って、新しい祝日データをNEW_FILEとしてダウンロードします。

成功または失敗に応じてログに記録し、失敗時はスクリプトを終了します。

5. 文字コード変換

if iconv -f SHIFT_JIS -t UTF-8 "${NEW_FILE}" > "${NEW_FILE}.utf8"; then
    mv "${NEW_FILE}.utf8" "${NEW_FILE}"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 文字コードの変換に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: 文字コードの変換に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

iconvコマンドを使って、ダウンロードしたCSVファイルの文字コードをSHIFT_JISからUTF-8に変換します。

変換後、一時ファイルを元のNEW_FILEにリネームして上書きします。

成功または失敗に応じてログに記録し、失敗時はスクリプトを終了します。

6. ファイルサイズの検証

if [ "$(stat -c%s "${NEW_FILE}")" -ge "$(stat -c%s "${BACKUP_FILE}")" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: ファイルサイズの検証に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: ファイルサイズが小さくなっています。" >> "${LOG_FILE}"
    exit 1
fi

新しいCSVファイルのサイズが、バックアップファイルのサイズ以上であることを確認します。

サイズが小さい場合はエラーとしてログに記録し、スクリプトを終了します。

7. バックアップファイルの削除

if rm "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: バックアップファイルを削除しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

バックアップファイルを削除します。

成功または失敗に応じてログに記録し、失敗時はスクリプトを終了します。

8. 新しいファイルのリネーム

if mv "${NEW_FILE}" "${SYUKUJITSU_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: ファイルのリネームに成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: ファイルのリネームに失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

新しいCSVファイルを、現在のSYUKUJITSU_FILEにリネームします。

成功または失敗に応じてログに記録し、失敗時はスクリプトを終了します。

9. 処理完了メッセージ

echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: 処理が完了しました。" >> "${LOG_FILE}"
exit 0

最後に、処理が成功したことをログに記録し、スクリプトを正常終了します。

まとめ

このシェルスクリプトは、祝日データの取得、バックアップ、変換、更新を自動で行います。

古いデータのバックアップ、新しいデータのダウンロード、文字コード変換、データの検証、更新の順に処理が進行します。

各ステップで成功・失敗をログに記録し、エラーが発生すると即座に終了します。

これにより、問題発生時に迅速に原因を把握でき、安全な自動更新を実現しています。

関連記事

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?