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のキャッシュ対策を自動化することができます。
一度仕組みを整えてしまえば、更新作業を忘れることもなくなり、運用の手間を大きく削減できます。
コメント