シェルスクリプトで月替わり画像とクエリパラメータを自動更新する方法

Webサイトの運営で、「月ごとに違う画像を表示したい」「ブラウザキャッシュを回避するために画像URLに年月を付けたい」といったニーズはよくあります。

この記事では、シェルスクリプトとcron(定期実行)を組み合わせて、月ごとの画像を自動でコピーし、CSSやPHPファイル内の画像URLのバージョンを現在の年月に置き換える方法を紹介します。


目的

  • 月別フォルダに格納された画像を、毎月自動でコピー
  • CSSやPHPファイル内の画像URLの ?202504 のようなクエリ部分を 当月の年月(例:202505)に自動更新
  • 手動作業なしで月初に更新される仕組みを構築

ディレクトリ構成(例)

/home/exampleuser/web/example-site.jp/public/wp-content/themes/mysite-theme/
├── assets/
│   └── images/
│       ├── month_image/
│       │   ├── 1/
│       │   ├── 2/
│       │   └── 12/
│       └── header_banner.png        ← コピー先(上書きされる)
├── assets/css/style.css
└── templates/page-header.php

月ごとの画像ファイル(例)

各月ディレクトリには、以下のような画像ファイルを6種類用意しておきます:

header_banner.png  
main_visual.png  
highlight_banner.png  
loading_icon_1.png  
loading_icon_2.png  
loading_icon_3.png

シェルスクリプトの内容:copy_images.sh

#!/bin/bash

# 現在の年月(例:202505)と月(1〜12)
year_month=$(date +%Y%m)
month=$(date +%-m)

# ディレクトリ設定
BASE_DIR="$HOME/web/example-site.jp/public/wp-content/themes/mysite-theme"
SOURCE_DIR="$BASE_DIR/assets/images/month_image/${month}"
DEST_DIR="$BASE_DIR/assets/images"
CSS_FILE="$BASE_DIR/assets/css/style.css"
PHP_FILE="$BASE_DIR/templates/page-header.php"

# 対象画像ファイル
FILES=(
  "header_banner.png"
  "main_visual.png"
  "highlight_banner.png"
  "loading_icon_1.png"
  "loading_icon_2.png"
  "loading_icon_3.png"
)

# OSによってsedのオプションを切り替え(macOSとLinux対応)
if [[ "$(uname)" == "Darwin" ]]; then
  sed_i_opt=(-i '')
else
  sed_i_opt=(-i)
fi

echo "コピー元: $SOURCE_DIR"
echo "コピー先: $DEST_DIR"
echo "現在の年月: $year_month"
echo "----------------------------------------"

# 画像コピー処理
if [ ! -d "$SOURCE_DIR" ]; then
  echo "エラー:月別画像ディレクトリが存在しません: $SOURCE_DIR"
  exit 1
fi

for file in "${FILES[@]}"; do
  if [ -f "$SOURCE_DIR/$file" ]; then
    cp "$SOURCE_DIR/$file" "$DEST_DIR/"
    echo "コピー完了: $file"
  else
    echo "スキップ(見つからない): $SOURCE_DIR/$file"
  fi
done

# CSS・PHPファイル内のクエリ文字列を年月で置換
update_version_query() {
  local target_file="$1"
  for img in "${FILES[@]}"; do
    sed "${sed_i_opt[@]}" -E "s|(${img//./\\.})\\?[0-9]{6}|\1?${year_month}|g" "$target_file"
  done
  echo "更新完了: $target_file"
}

update_version_query "$CSS_FILE"
update_version_query "$PHP_FILE"

echo "スクリプト処理が完了しました($year_month)"

cronによる自動化(毎月1日の深夜に実行)

以下のようにcrontabを設定することで、スクリプトを自動実行できます:

0 0 1 * * bash /home/exampleuser/scripts/copy_images.sh >> /home/exampleuser/scripts/copy_images.log 2>&1
  • 毎月1日の午前0時に実行されます
  • 実行ログは copy_images.log に記録されます

実装時のポイント

ポイント内容
ファイル名CSSやPHPで参照している画像名と完全一致する必要あり
クエリ形式image.png?202504 のように年月6桁が付与されている形式であること
sed の仕様差macOS と Linux で -i オプションの書き方が違うため、スクリプト内で自動判定しています
実行権限chmod +x copy_images.sh を忘れずに

まとめ

このように、シェルスクリプトとcronを組み合わせることで、月ごとの画像更新とクエリ付きURLのキャッシュ対策を自動化することができます。

一度仕組みを整えてしまえば、更新作業を忘れることもなくなり、運用の手間を大きく削減できます。

コメント

タイトルとURLをコピーしました