おはようございます。くろねこです。
はじめに、今回の記事は【講釈】が非常に多いです。すみません。
そこで、そのまま利用可能なバッチ(以下)を2本掲載します。
① 日時チェック用バッチ
② 日時設定用バッチ
注意事項にしたがって利用することで、バッチの実行制御が可能になります。
手っ取り早く使ってみたい方は、目次から「日時チェック用バッチの動作構成図」をクリックしてください。
- 【講釈】はじめに
- 【講釈】タスクスケジューラではだめなの?
- 【講釈】日々の運用の中で
- 【講釈】不安要素を減らすために
- 日時チェック用バッチの動作構成図
- 日時チェック用バッチ(CheckDateTime.bat)
- 日時設定用バッチ (SetDateTime.bat)
- タスク実行用バッチ (SampleTask.bat)
- おわりに
【ご注意】
本サイトを参考に作成したものは、自己責任でお願いします。
実行前のレビューやテストを必ず実施してください。
それでは、今回もよろしくお願いします。
【講釈】はじめに
日時チェック用バッチ は、純粋にバッチの機能のみで作成したものです。
C# や vbscriptなどで作ったほうが、もっと簡単に作成できますが、ここで掲載したのは、
ハッチだけでここまでできる!
のサンプル的な意味あいが強いからです。
バッチでできることは限られていますが、工夫することでここまでできるのです。
本当はもっと簡単に と思っていたのですが、テストをしてみると「雑」な部分が露呈し、途中からは、半分意地になってしまいました(笑)
【講釈】タスクスケジューラではだめなの?
ところで、日時チェック用バッチなんか作らなくても、タスクスケジューラでいいんじゃないの?
と思う方、多いでしょうね。
普通なら、特定の日時に処理を実施するには、Windowsではタスクスケジューラを利用しますが、くろねこの経験上、確実に運用する場合には、もっと簡単に実施できなければならないことが多かったのです。
【講釈】続きます m(_ _)m
【講釈】日時指定実行の必要性
運用の現場では、よくあるシチュエーションとして、以下のようなことがあります。
① 特定の日時(深夜や休日など)にある処理を1回だけ実行したい
② 定期的に処理を実施したい
③ 必要なタイミングで、ある処理を実施したい(タイミングは不定期)
言葉にするとわかりにくいですね。
ということで、具体的な例で言うと以下のようなケースです。
①は 「○月□日 深夜0:00 に c:\task\task0001.bat を実行する」
このケースは、ユーザのいない時間帯にサーバをリブート(再起動)したいときなどです。
②は 「毎週日曜日 深夜2:00 に c:\task\task0002.bat を実行する」
このケースは、おもにバックアップなどの用途になります。
③は 「次回は、○月□日 22:00 に、c:\task\task0003.bat を実行する」
このケースは、例えばですが
データの登録は都度実施していて、それらのデータのうち、有効日が ○月□日 22:00 のものを c:\task\task0003.bat で他のシステムへ連携させる みたいなものです。
「必要なタイミング」が「データ有効日」、「c:\task\task0003.bat」の内容が「別のシステムに連携する」にあたります。
これら3つのケースの作業の流れは下記のようになります。
①は、1回限りのタスクとなりますので、実行するプログラムの作成とタスクスケジューラでのタスク登録という流れになります。
これは、一発勝負となりますので、入念なレビューで対応するしかありません。
②は、①と同様に実行するものの作成とタスクスケジューラでのタスク登録でほぼ同じ流れになります。(繰り返し設定の違いのみ)
こちらのケースも基本的に①と同じですが、定期的に実行するものですので初回に問題があったとしても補正の余地があります。
とは言っても初回で正しく動作するようしっかりレビューですね。
問題は③のケースです。
初回は①のケースと同様に、
1回のみ実行のタスク、実行するプログラムの作成とタスクスケジューラでのタスク登録という流れは同じです。
ですが、「必要なタイミング」が決まった段階で、タスクスケジューラを開き、1回目で登録したタスクの実行日時を変更することになります。
それ以降、実行タイミングが決まる都度、実行日時の変更作業を実施しなければなりません。
【講釈】うまく動作しない!?
しかし、このタスクスケジューラでタスクを登録したが、目的の日時に実行されていなかった経験をお持ちの方、多いのではないでしょうか。
だから、
うまく動作しないリスクを極力低くするために、
必要以上であっても、最大の権限(管理者権限)で動作するように設定することが現場では多くなります。
当然ですが、管理者権限で動作するタスクの登録は管理者アカウントでWindowsにログオンしての操作となります。
要するに、タスクを確実に動作させるためには、最大限の権限でWindowsを操作したほうが楽なのです。
それが、多少のセキュリティリスクを含んでいたとしても・・・
【講釈】日々の運用の中で
上記①~③において、タスク登録は十分な経験をもった方が実施されると思います。
多くの場合、一連の処理をひとつのバッチにまとめ、そのバッチをタスク登録するのが一般的です。
しかし、通常のプログラム作成ほど十分な「設計」をすることなく、「さらっと」バッチを作成するため、どういう思いでそのバッチが出来上がったのか? が残っていないことがほとんどなんです。
だから、一度、動かしたものは極力触りたくないのです。
ましてや、他人のバッチなんて触りたくもないし、自分のものを触らせたくもありません。
以上のことから、
①~③のタスク登録
タスク登録(バッチ作成を含む)をする人
→ バッチの先で動くプログラムの設計者・製作者 (十分な経験あり)
タスク登録(バッチ作成を含む)をするタイミング
→ 時間的にも精神的にも余裕があるときに実施する。(バッチ内にコメントを残す)
③の2回目以降の実行日時登録
タスクの実行日時変更をする人
→ 初回タスク登録者がベスト
→ 他の人が実施する場合、設定変更後に初回タスク登録者による設定内容の確認
何れの場合も、タスク化ができていない場合は、
プログラムの設計者・製作者が作成した手順をメモ帳などで具体的に箇条書きし、実行タイミングになったら、手作業で処理することになります。
のちに、タスク登録(バッチ作成)の段階で、そのメモが設計書の役割となります。
と、まあ、こんな感じでやってますが
作業のピーク時となると、思わぬところで、つまらんミスが起きてしまいます。
特に、③の2回目以降の日時設定時で、一度、正常動作している安心感からか、軽く操作してしまうのです。
しかも、よりによってというタイミングで操作ミス
管理者権限でWindowsを操作、何気ない操作でミスを・・・
たった、日時を変更するだけだったのに・・・
【講釈】不安要素を減らすために
この日時を変更するだけの操作
もっと簡単に、確実にできないものでしょうか?
もっと言えば、
管理者アカウントのパスワードを教えたくなかった別のメンバへの作業分担できないものでしょうか?
ということで、
・ 実行したい日時のみを指定する
・ 管理者権限が無くても日時を指定できる
この2点を実現するために、今回の 日時チェック用バッチ を利用することで実現できます。
日時チェック用バッチの動作構成図
日時チェック用バッチを利用したタスクの動作構成図です。
関連するファイルは以下の表をご覧ください。
日時チェック用バッチ(CheckDateTime.bat)
日時チェック用のメインとなるバッチファイルです。
バッチのコード
以下が、日時チェック用バッチ です。
コード部分をダプルクリックすると全選択されますので、コピーし、テキストエディタ(メモ帳など)貼り付け、CheckDateTime.bat という名前で保存してください。
文字コードはANSIです。
保存先は、この後、説明する タスク実行用バッチ と同じフォルダにしてください。
@echo off rem ***************************************************** rem CheckDateTime.bat rem バッチで日時を確認するサンプル rem 日時チェック用ファイルに記述された日時と rem 指定日時を比較した結果を終了コードとして返却する。 rem 終了コード 比較結果 rem 0 指定日時 ≧ 日時チェック用ファイルの日時 rem (チェックファイルの日時を過ぎた) rem 8 指定日時 < 日時チェック用ファイルの日時 rem (チェックファイルの日時より前) rem 12 日時チェック用ファイルが存在しない rem 16 引数なし rem ***************************************************** cd /d %~dp0 set @Log=%~n0.log echo %~n0 started : %date% %time% > %@Log% set @RC=0 :ChkParam echo :ChkParam >> %@Log% if "%1"=="" goto Usage set @ChkDtTmFile=%1 set @dt01=%2 %3 if "%time:~0,1%"==" " ( set @time=0%time:~1% ) else ( set @time=%time% ) if "%2"=="" ( echo Check date time is current date time >> %@Log% set @dt01=%date% %@time:~0,5% ) else ( if "%3"=="" ( echo Check date time is current time >> %@Log% set @dt01=%2 00:00 ) ) goto ChkFile :Usage echo. echo :Usage >> %@Log% echo * %0 usage ********************************** echo %0 日時チェック用ファイル 比較する日付 時刻 echo. echo 日時チェック用ファイルには、1行目に下記の形式で日付時刻情報を記述してください。 echo yyyy/mm/dd hh:mm echo. echo 比較する日付 時刻 は下記の形式で指定してください。 echo yyyy/mm/dd hh:mm echo. echo e.g. echo %0 checkfile.txt 2022/09/01 13:00 echo 2022/09/01 13:00 とファイルに記述された日時を比較する場合 echo %0 checkfile.txt echo 現在の日時とファイルに記述された日時を比較する場合 echo (比較する日付のみ指定した場合、時刻は0:00として扱われます。) echo. set @RC=16 goto Ending :ChkFile echo :ChkFile >> %@Log% if exist %1 goto chkdate echo %1 が見つかりません。 echo %1 が見つかりません。 >> %@Log% set @RC=12 goto Ending :ChkDate echo :ChkDate >> %@Log% rem Read first record only for /f "usebackq delims=" %%t in (%@ChkDtTmFile%) do ( set @dt02=%%t goto Compare ) :Compare echo :Compare >> %@Log% echo Check File : %@dt02% >> %@Log% echo Compare : %@dt01% >> %@Log% if "%@dt01%" geq "%@dt02%" ( set @RC=0 del %@ChkDtTmFile% goto Ending ) set @RC=8 goto Ending :Ending echo :Ending >> %@Log% echo Return code : %@RC% >> %@Log% echo %~n0 ended : %date% %time% >> %@Log% set @dt02= set @dt01= set @time= set @ChkDtTmFile= set @Log= exit /B %@RC% set @RC=
保存したフォルダをコマンドプロンプトで開き、
CheckDateTime (リターン)
としたときに、下記のように表示されれば、問題ありません。表示されない場合は文字コードが間違っています。
バッチの使用方法
日時チェック用バッチは、
引数で指定された、実行日時ファイル に記載された 日付と時刻 とバッチ実行の日時を比較します。
結果はバッチの終了コード(ERRORLEVEL)で通知されます。
結果は下記4パターンてす。
0 : 指定日時を経過した
8 : まだ、経過していない
12: 実行日時ファイルが存在しない
16: 引数なし
日時チェック用バッチ の使い方は以下のようになります。
cmd /c .\CheckDateTime.bat 実行日時ファイル if errorlevel 8 ( goto ending ) (メイン処理:指定時刻になった場合の処理) :ending
日時設定用バッチ (SetDateTime.bat)
実行日時ファイルを作成するためのバッチファイルです。
バッチのコード
以下が、日時設定用バッチ です。
コード部分をダプルクリックすると全選択されますので、コピーし、テキストエディタ(メモ帳など)貼り付け、SetDateTime.bat という名前で保存してください。
文字コードはANSIです。
保存先は、タスク実行用バッチの実行日時を設定する人のPCの任意のフォルダになります。
ショートカットをデスクトップに作っておくと便利です。
@echo off rem ***************************************************** rem SetDateTime.bat rem 日時チェックバッチ用の実行日時ファイル作成用バッチ rem ***************************************************** cd /d %~dp0 set @Log=.\%~n0.log echo Executed : %date% %time% > %@Log% set @output=\\SERVER\SHARE\SampleTask.txt if not exist %@output% goto inpdate echo. echo 既に実行日時が登録されています。(下記) echo 処理を続行する場合、実行日時は上書きされます。 type %@output% echo. set /p @check="続行する場合は そのままEnterキー、キャンセルの場合は 他の文字 + Enter です。" if not "%@check%"=="" goto cancel echo. :inpdate echo :inpdate >> %@Log% echo 処理実行日時を指定してください set /p @dttm="入力は yyyy/mm/dd hh:mm 形式です >>> " echo. echo %@dttm% に処理を実行します。よろしいですか? set /p @check="続行する場合は そのままEnterキー、キャンセルの場合は 他の文字 + Enter です。" if not "%@check%"=="" goto cancel rem 指定日時を出力 echo %@dttm%> %@output% echo. echo 指定日時を %@output% に出力しました。 goto ending :cancel echo :cancel >> %@Log% echo 処理を中止しました。 echo. :ending echo :ending >> %@Log% set @output= set @check= echo. pause
バッチの使用方法
保存したフォルダをコマンドプロンプトで開き、
SetDateTime (リターン)
あとは、バッチが指示する内容にしたがって、操作をすれば、実行日時ファイルが生成されます。
タスク実行用バッチ (SampleTask.bat)
本来、ユーザが特定の日時に実行したいタスクのバッチファイルになります。
ここでは、本来実施したい部分(「メイン処理」)がダミーとなっているファイルです。
動作テストが終わったら、ダミー部分を本物の処理に書き換えてください。
バッチのコード
@echo off rem ***************************************************** rem SampleTask.bat rem サンプルタスク実行用バッチ rem ***************************************************** cd /d %~dp0 echo %~nx0 start at %date% %time% > %~n0.log :wait10s echo 10秒時間調整します >> %~n0.log timeout /T 10 /NOBREAK :setparam echo setparam >> %~n0.log set @StartTm=%time% set @ExecDateTime=\\SERVER\SHARE\SampleTask.txt :chkexec echo chkexec >> %~n0.log cmd /c .\CheckDateTime.bat %@ExecDateTime% if errorlevel 8 ( echo 指定時刻になっていません >> %~n0.log goto ending ) echo メイン処理を開始します >> %~n0.log rem *** メイン処理 ここから ****************************************************** rem *** メイン処理 ここまで ****************************************************** echo メイン処理が終了しました >> %~n0.log :ending echo ending >> %~n0.log set @EndTm=%time% echo %~nx0 end at %date% %time% >> %~n0.log echo Start time : %@StartTm%, End time : %@EndTm% >> %~n0.log set @ExecDateTime= set @Work= set @StartTm= exit /B rem ** Sub routine ********************************************************************** :trim rem Function : trim specified parameter set @work=%1
バッチの使用方法
タスクスケジューラで、SampleTask.batを実行するタスクを登録します。
タスク登録については要点のみ記載します。
・ 基本タスクの作成
・ 名前設定
・ タスクトリガー
毎日 開始日:任意 時刻:0:00
繰り返し間隔 1時間
・ 操作 プログラムの開始
プログラム/スクリプト SampleTask.batの完全パス名
開始(オプション) SampleTask.batが保存されたフォルダ
おわりに
かなり長文の記事になってしまいました。
ここまで、ご覧いただき、ありがとうございます。
ここで、ちょっとだけ
タスクスケジューラでのタスク起動は実際には指定時刻よりも前に起動されてしまうケースがあります。
例えば、10:00:00に起動するタスクですぐに時刻を表示してみると、 9:59:59 だったりすることがあるのです。
くろねこの経験上では、最大5~7秒の場合もありました。
時刻を見ながら動作するようなタスクの場合は致命的なケースにつながる可能性もあります。
注意が必要です。
この対策は、タスク起動されたバッチの冒頭で10秒程度、時間調整することで回避できます。
それでは、また。
バッチ特集の過去の記事は下記をクリック願います。