本記事は技術情報の共有ではなく、過去の業務実績を残すためのポートフォリオとして限定公開している記事になりますので、可能な限りURLの拡散は控えていただきますようお願いいたします。
目的
atコマンドを利用したバッチやDBレコード取得の自動実行方法を確立する。
背景
私がQCとして試験していた時、深夜のバッチ実行やAPIリクエストの実行を求められることがありました。
試験実施者が深夜に自宅で対応する方針となっていたが、実施者の負担となってしまうため、提示作業ないでコマンド実行の予約をする方針で作業を進めることとなった。
類似したコマンドにcronがあるが、試験環境の都合上使用できなかったため、消去法でatコマンドを採用。
atコマンドを実行するための環境は、チーム内にいたとても素晴らしい方が立案し整備しました。
その方のノウハウを横流しする形になってしまい大変恐縮ですが、備忘録として、自身が経験した業務を経歴として残したいためにここへ記載させていただきます。
あくまで自分が現場で実践が行われて効果的だった方法を経験談として記載させていただきます。
内容は一般化し、人、会社、団体が特定されないようにします。
ディレクトリ構成
┣ SET-AT.sh
┣ exec_example_batch.sh
┣ get_example_table.sh
┗ outfile/
┣ example_batch_yyyymmddhhmmss.log
┗ get_example_table_yyyymmddhhmmss.log
各ファイルについて
exec_example_batch.sh
#!/bin/bash
#ログファイル名と生成場所の宣言
outf="./outfile/example_batch_"`date +"%Y%m%d%H%M%S"`".log"
# ログファイルの生成
touch $outf
# 自動実行開始する日時をログファイルに出力
echo '**** example_batch *** START **' `date` '**********' >> $outf
# バッチ実行し、実行結果をログファイルに出力
sh /PATH_TO_BATCH/example_batch.sh >> $outf
# 自動実行終了する日時をログファイルに出力
echo '**** example_batch *** END **' `date` '**********' >> $outf
get_example_table.sh
#!/bin/bash
# ログファイル名と生成場所の宣言
outf="./outfile/get_example_table_"`date +"%Y%m%d%H%M%S"`".log"
# ログファイルの生成
touch $outf
# 自動実行開始する日時をログファイルに出力
echo '**** example_table *** START **' `date` '**********' >> $outf
# select文を生成し、mysqlログイン後に実行、実行結果をログファイルに出力
echo 'select * from example_table where example_column in ("a","b")\G' | mysql -u username -p password ExampleDatabase >> $outf
# 自動実行終了する日時をログファイルに出力
echo '**** example_table *** END **' `date` '**********' >> $outf
SET-AT.sh
#!/bin/bash
# 自動実行する日付をyyyymmdd形式で宣言
EXEC_DATE=yyyymmdd
# 自動実行する時刻をhhmm形式で設定し、実行するファイルを指定
at -t `echo $EXEC_DATE`hhmm -f ./exec_example_batch.sh
at -t `echo $EXEC_DATE`hhmm -f ./get_example_table.sh
実施方法
例として、以下のスケジュールで実行したい場合の設定方法を記載します。
- 2025年10月31日21時にexample_batch.shの実行
- 2025年10月31日22時にexample_tableからのデータ取得
事前準備
atdサービスの起動
# atdサービスの状態確認
service atd status
#サービス起動
service atd start
atコマンドを実行するためには、atdサービスが起動中になっている必要があります。
atdサービスの状態確認し、もし停止中であればservice atd startでサービスを起動してください。
get_example_table.shの編集
#!/bin/bash
# ログファイル名と生成場所の宣言
outf="./outfile/get_example_table_"`date +"%Y%m%d%H%M%S"`".log"
# ログファイルの生成
touch $outf
# 自動実行開始する日時をログファイルに出力
echo '**** example_table *** START **' `date` '**********' >> $outf
# select文を生成し、mysqlログイン後に実行、実行結果をログファイルに出力
echo 'select * from example_table where example_column in ("valueA","valueB")\G' | mysql -u username -p password ExampleDatabase >> $outf
# 自動実行終了する日時をログファイルに出力
echo '**** example_table *** END **' `date` '**********' >> $outf
select文を確認し、欲しいレコードが取得できている条件となっているかを確認します。
example_columnカラムの値がvalueAもしくはvalueBとなっているレコードの取得を行いたいときは上記となります。
exec_example_batch.shの内容確認
#!/bin/bash
#ログファイル名と生成場所の宣言
outf="./outfile/example_batch_"`date +"%Y%m%d%H%M%S"`".log"
# ログファイルの生成
touch $outf
# 自動実行開始する日時をログファイルに出力
echo '**** example_batch *** START **' `date` '**********' >> $outf
# バッチ実行し、実行結果をログファイルに出力
sh /PATH_TO_BATCH/example_batch.sh >> $outf
# 自動実行終了する日時をログファイルに出力
echo '**** example_batch *** END **' `date` '**********' >> $outf
バッチ実行に使用するファイルは書き換える必要がないため、ファイル内容が誤って書き換えられていないかを確認するくらいでよいです。
SET-AT.shの編集
#!/bin/bash
# 自動実行する日付を20251031で宣言
EXEC_DATE=20251031
# 自動実行する時刻を2100、2200で設定し、実行するファイルを指定
at -t `echo $EXEC_DATE`2100 -f ./exec_example_batch.sh
at -t `echo $EXEC_DATE`2200 -f ./get_example_table.sh
自動実行を行う日付、時刻、自動実行するファイルを指定します。
ここで注意して欲しいのが、必ず未来の日時になっているかです。
過去の日時を指定してしまった場合、即時実行されてしまう可能性があるからです。
ネット上で「過去の日時をatコマンドで指定した場合実行が行われない」という記載を目にしたことがあるのですが、試験中実際に過去の日時を指定したときは予約が行われず即時実行されてしまいました。
そのため、ここの日付と時刻だけは十分に注意して入力してください。
予約実施
sh SET-AT.sh
job 134 at 2024-10-31 21:00
job 135 at 2024-10-31 22:00
SET-AT.shを実行するだけで予約完了です。
予約に成功すると、SET-AT.shで記載したatコマンドの行の数だけjob 134 at 2024-10-31 21:00のようにジョブの通し番号と実行予定日時が表示されます。
at -l
job 134 at 2024-10-31 21:00
job 135 at 2024-10-31 22:00
at -lで予約中のジョブを一覧表示できます。
運用時のアドバイス
用意したディレクトリとファイルの権限は適切かを事前に確認すること
atコマンドの実行に成功したものの、atコマンド自体がファイルの読み込み等できないということがありました。
実運用前にファイルの読み込みが適切に行えるかを確認した方がいいかと思います。
私が実施した際はchmod 755を統一して設定していました。
atdサービスを起動中にする際は、ホスト管理者へ確認をすること
atdサービスは基本停止中になっていることの方がデフォルトです。
他者が管理しているホストのatdサービスを起動中にする際は、ホストの管理者へ起動しても問題ないか確認をとった方がいいかと思います。
QA
想定される質問とその回答をここに記載します。
Q:atコマンドで予約されたジョブはサーバ再起動後も残りますか?
A:残りません。
再度予約し直してください。
Q:atコマンドで同じ時間に複数のジョブを登録するとどうなりますか?
A:問題なく登録されます。
それぞれ独立したジョブIDで実行されます。
ただし、同時実行によるリソース競合(例:DBアクセスやファイルロック)には注意してください。
Q:日付を跨ぐスケジュールを登録したい場合はどうすればいいですか?
A:翌日の日付を格納する変数を別途宣言してあげれば問題ありません。
例として、以下のスケジュールで実行したい場合の設定方法を記載します。
変数名はあくまで例ですので、ご自身で好きな変数名を宣言してもらって構いません。
- 2025年10月31日21時にexample_batch.shの実行
- 2025年11月01日02時にexample_tableからのデータ取得
#!/bin/bash
# 自動実行する日付を宣言
EXEC_DATE=20251031
EXEC_DATE_NEXTDAY=20251101
# 自動実行する時刻を設定し、実行するファイルを指定
at -t `echo $EXEC_DATE`2100 -f ./exec_example_batch.sh
at -t `echo $EXEC_DATE_NEXTDAY`0200 -f ./get_example_table.sh