Cronを使用して定期的なタスクを自動化し、実行できない場合の原因調査方法。
CronはLinuxシステムで定期的なタスクを自動実行ツールです。バックアップや、定期的なフォルダー監視、通知等使用します。 Ubuntu環境でのCronジョブの設定方法と、Cronが期待通りに動作しない場合の一般的なトラブルシューティング手順を解説します。
Cronジョブを追加するには、crontab -e コマンドを使用します。これにより、現在のユーザーのcrontabファイルがエディタで開かれます。
crontab -e
エディタが開いたら、以下の形式でジョブを追加します。
分 時 日 月 曜日 実行コマンド
cronの実行日時の指定はここをご参考ください。
例: 毎日午前3時30分に /path/to/your/script.sh を実行する場合
30 3 * * * /path/to/your/script.sh
期待通りに起動しなかった場合確認することは
上記が確認できれば恐らく起動できるはずです。 cronとターミナルでは挙動が異なります。パスが登録されていないためターミナルでは起動できるのに、cronでは動かない事があります。また、コマンドもフルパスを推奨します。
パスを追加して実行させてみる。 一般的なパスを初めに追加してあげると正常に起動してくれるかもしれません。
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 3 * * * /usr/bin/env bash -lc '実行するコマンド.sh >> 必要あれば実行後ログを保存.log 2>&1'
Node.jsスクリプトをCronで実行する場合も、同様にフルパスを指定し、必要に応じて PATH を設定します。Node.jsの実行ファイル (node) のパスも確認してください。
which node
0 3 * * * /usr/bin/node /path/to/your/node_script.js >> /path/to/your/log.log 2>&1
Cronサービスが正しく動作しているかを確認するには、systemctl status cron コマンドを使用します。
systemctl status cron
出力で Active: active (running) と表示されていれば、サービスは正常に動作しています。
Cron環境では、通常のシェル環境とは異なり、PATH 環境変数が最小限に設定されていることがあります。そのため、コマンドのフルパスを指定しないと実行できない場合があります。スクリプト内で使用するコマンドのパスが通っていない場合は、crontabの先頭に PATH を明示的に設定することをお勧めします。
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# 以下にCronジョブを記述
30 3 * * * /path/to/your/script.sh
Cronで実行するスクリプトには、実行権限が付与されている必要があります。以下のコマンドで実行権限を付与します。
chmod +x /script.sh
Cronジョブが実行されたかどうか、またはエラーが発生していないかを確認するには、システムログを調べます。grep CRON を使用してCron関連のログエントリをフィルタリングできます。
sudo cat /var/log/syslog | grep CRON
このログには、Cronジョブの開始、終了、および発生した可能性のあるエラーに関する情報が含まれています。
Cronジョブの実行時間は、システムのタイムゾーン設定に依存します。意図した時間にジョブが実行されない場合は、タイムゾーン設定を確認してください。
現在のシステム時刻とタイムゾーンを確認するには、以下のコマンドを使用します。
date
より詳細なタイムゾーン情報を確認するには、timedatectl コマンドを使用します。
timedatectl
もしタイムゾーンが日本(Asia/Tokyo)でない場合は、以下のコマンドで変更できます。
sudo timedatectl set-timezone Asia/Tokyo
変更後、date または timedatectl コマンドでタイムゾーンが正しく設定されたか確認してください。
rsyncは絶対に間違えないようにご注意ください。
特に--deleteオプションは危険です。
30 3 * * * rsync -av --delete /home/user/files/ /mnt/backup/ >> /var/log/rsync.log 2>&1
#!/bin/bash
# 元と出力先ディレクトリ
SRC_DIR="/home/user/videos/original"
DST_DIR="/home/user/videos/compressed"
# 出力フォルダがなければ作る
mkdir -p "$DST_DIR"
# ログ開始
echo "=== $(date '+%Y-%m-%d %H:%M:%S') 開始 ===" >> /home/user/logs/compress_videos.log
# 元フォルダ内の動画を順に処理
for file in "$SRC_DIR"/*.mp4; do
[ -e "$file" ] || continue # ファイルが無いときスキップ
# 出力ファイル名を設定
filename=$(basename "$file")
output="$DST_DIR/$filename"
# 既に変換済みならスキップ
if [ -f "$output" ]; then
echo "スキップ: $filename(既に存在)" >> /home/user/logs/compress_videos.log
continue
fi
echo "変換中: $filename" >> /home/user/logs/compress_videos.log
# ffmpegで圧縮(例:解像度720p、ビットレート1Mbps、音声128kbps)
/usr/bin/ffmpeg -i "$file" -vf scale=-1:720 -b:v 1M -b:a 128k -preset medium -movflags +faststart "$output" -y >> /home/user/logs/compress_videos.log 2>&1
echo "完了: $filename" >> /home/user/logs/compress_videos.log
done
echo "=== $(date '+%Y-%m-%d %H:%M:%S') 終了 ===" >> /home/user/logs/compress_videos.log
echo "" >> /home/user/logs/compress_videos.log
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 4 * * * /usr/bin/env bash -lc '/home/user/scripts/compress_videos.sh >> /home/user/logs/compress_cron.log 2>&1'
UbuntuにおけるCronジョブの設定方法と、Cronが期待通りに動作しない場合の確認方法を解説しました。timezoneをわりと忘れてしまいます。何度かやりました...
定期的なバックアップもcronとrsyncを使用すれば実装ができます。