設定ファイルを変更する前にバックアップを残したい、ログを日次でリネームしたい——こうした場面で役立つのが、コマンド置換を使ったファイル名への日付自動付与です。まず結論として、最もよく使う基本形を示します。
# 設定ファイルを今日の日付付きでバックアップ
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.$(date +%Y%m%d)
実行すると nginx.conf.20250724 のような名前のファイルが生成されます。$(date +%Y%m%d) の部分がコマンド置換で、シェルがその時点の日付文字列に展開してからコマンド全体を実行します。
日付フォーマットの指定方法
date コマンドは + 以降にフォーマット文字列を渡すことで出力形式を制御できます。主要な指定子は以下のとおりです。
| 指定子 | 内容 | 出力例 |
|---|---|---|
%Y | 西暦年(4桁) | 2025 |
%y | 西暦年(下2桁) | 25 |
%m | 月(01〜12) | 07 |
%d | 日(01〜31) | 24 |
%H | 時・24時間制(00〜23) | 14 |
%M | 分(00〜59) | 30 |
%S | 秒(00〜59) | 00 |
%a | 曜日略称 | Thu |
%b | 月名略称 | Jul |
日付と時刻を組み合わせた %Y%m%d%H%M%S は、1日に複数回バックアップを取る場面や、スクリプトで秒単位の一意性が必要な場面で重宝します。
$ date +%Y%m%d%H%M%S
20250724143000
コマンド置換は $() 形式を使う
古いスクリプトではバッククォート(`date +%Y%m%d`)で囲む書き方が見られますが、現在の運用では $() 形式が標準です。理由は3点あります。
- ネストが直感的に書ける(
$(outer $(inner))のように記述できる) - バッククォートはエスケープルールが複雑でミスを招きやすい
- POSIX準拠のシェル(bash・zsh・dash)すべてで動作する
バッククォートはシングルクォートと見た目が紛らわしく、コードレビューやペア作業時に読み間違いが起きやすいため、チームの規約として $() を採用しているケースがほとんどです。以降の例はすべて $() で統一します。
実務でよく使うリネーム・バックアップパターン
ある運用現場では、デプロイ前に以下のワンライナーを定番としています。変更前後のファイルが同じディレクトリに残るため、ロールバック時の差分確認が即座に行えます。
# 秒まで含めた日時付きバックアップ(1日複数回の変更にも対応)
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +%Y%m%d_%H%M%S)
ログファイルのリネームには mv と組み合わせます。元のファイル名を日付付きのアーカイブ名に変えつつ、必要に応じて別ディレクトリに移動できます。
# 今日付けのアーカイブ名にリネーム
mv /var/log/app/access.log /var/log/app/access.log.$(date +%Y%m%d)
# バックアップ先ディレクトリに日付入りのファイル名でコピー
cp /var/log/app/access.log /var/backup/access_$(date +%Y%m%d).log
スクリプト内でバックアップ先ディレクトリを日付ごとに用意する場合は、先にディレクトリを作成してからコピーします。
BACKUP_DIR="/var/backup/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
cp /etc/myapp/*.conf "$BACKUP_DIR/"
変数に日付を一度格納しておくと、同一スクリプト内で複数回使っても日付がずれません。特に深夜0時をまたぐ可能性があるバッチ処理では、スクリプト冒頭で日付を変数に固定しておくことが重要です。
複数ファイルをまとめて日付付きにする
ディレクトリ内の特定パターンにマッチするファイルをまとめてバックアップするには、for ループと組み合わせます。
DATE=$(date +%Y%m%d)
for f in /etc/myapp/*.conf; do
cp "$f" "${f}.${DATE}"
done
ループの外で DATE 変数を定義することで、ループ内で何度参照しても同じ日付文字列が使われます。$f はダブルクォートで囲む習慣をつけてください。ファイル名にスペースが含まれていた際の単語分割を防ぎます。
タイムゾーンと日付境界の注意点
date コマンドはシステムのタイムゾーン設定を参照します。UTC運用のサーバーでは JST(日本標準時)との9時間差に注意が必要です。出力が想定と異なる場合はまずタイムゾーンを確認してください。
# タイムゾーン確認(systemd 環境)
timedatectl
# 一時的に JST で出力したい場合(システム設定は変えない)
TZ=Asia/Tokyo date +%Y%m%d
本番環境でタイムゾーンを恒久変更するには timedatectl set-timezone Asia/Tokyo を使います。ただし、既存ログのタイムスタンプ解釈や cron ジョブの実行タイミングに影響するため、事前に影響範囲を確認してから変更してください。
深夜バッチで「前日の日付」でファイルをまとめたい場面では、GNU date の相対日付指定が使えます。
# 昨日の日付を取得(Linux / GNU date)
date -d yesterday +%Y%m%d
# N 日前の日付(例:7日前)
date -d "7 days ago" +%Y%m%d
この -d オプションは GNU date 固有の拡張です。macOS や一部の BSD 系では date -v-1d +%Y%m%d と書き方が異なります。異なる OS をまたいで動作するスクリプトを書く場合は、この差異を意識してください。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
