Windowsでの定型業務を自動化する際、コマンドプロンプト(バッチファイル)は非常に強力なツールです。
しかし、複数のコマンドを連続して実行させる際、一つのコマンドがエラーを返しただけで処理全体が意図せず止まってしまったり、後続の重要な処理が実行されなかったりすることがあります。
効率的な自動化を実現するためには、エラーが発生しても柔軟に処理を継続させる「エラー制御」の技術が欠かせません。
本記事では、コマンドプロンプトでエラーを無視して連続実行するための具体的な記述方法や、バッチ処理を中断させないための高度なテクニックについて詳しく解説します。
コマンドプロンプトにおける連続実行の基本仕様
コマンドプロンプトで複数のコマンドを実行する場合、基本的には記述した順序に従って一行ずつ処理が実行されます。
通常のバッチファイルであれば、ある行のコマンドでエラーが発生しても、そのまま次の行の処理へと移るのが標準的な挙動です。
しかし、一部のコマンドや複雑なスクリプト構成においては、エラーの発生が致命的な停止を招くことがあります。
また、コマンド同士を接続する「コマンド結合子」の使い方を誤ると、エラー時に後続処理がスキップされてしまうため注意が必要です。
まずは、連続実行を制御するための基本的な記号(演算子)の性質を理解しましょう。
コマンド結合子による実行制御の違い
コマンドプロンプトでは、1行の中に複数のコマンドを記述して連続実行させることができます。
このとき使用する記号によって、エラー時の挙動が大きく変わります。
| 演算子 | 意味 | エラー時の挙動 |
|---|---|---|
& | 順次実行 | 前のコマンドの成否に関わらず、次のコマンドを実行する |
&& | 成功時実行 | 前のコマンドが成功(終了コード0)した場合のみ、次を実行する |
|| | 失敗時実行 | 前のコマンドが失敗(終了コード1以上)した場合のみ、次を実行する |
エラーを完全に無視して次の処理へ進みたい場合は「&」を使用するのが基本です。
逆に、特定のコマンドが失敗したときだけリカバリー用の処理を走らせたい場合には || が有効に機能します。
エラーを無視して処理を継続する具体的な記述テクニック
バッチ処理において、特定のエラー(例えば「対象のファイルが見つからない」など)を無視して強引に処理を完遂させたいケースは多々あります。
ここでは、実務で使える具体的な記述パターンを紹介します。
1. アンパサンド(&)でコマンドを連結する
最も単純な方法は、コマンドを & でつなぐことです。
これにより、前のコマンドがどのような結果であっても、必ず次のコマンドが呼び出されます。
@echo off
rem 存在しないファイルを削除しようとしても、エラーを表示して次へ進む
del non_existent_file.txt & echo 次の処理を開始します。
pause
この実行結果は以下のようになります。
ファイルが見つかりませんでした。
次の処理を開始します。
続行するには何かキーを押してください . . .
このように、エラーメッセージ自体は出力されますが、スクリプトの進行は止まりません。
2. エラー出力を破棄して静かに実行する
エラーが発生した際に、画面上にエラーメッセージ(標準エラー出力)を表示させたくない場合は、リダイレクト機能を使用して出力を破棄します。
@echo off
rem エラーメッセージを NUL デバイスに捨てる
dir non_existent_dir 2>NUL & echo エラーを隠して続行しました。
pause
2>NUL という記述は、エラー出力(ハンドル番号2)を「空(NUL)」という特別な場所に送ることを意味します。
これにより、ユーザーにはエラーが起きたことを悟られずに、スムーズに次のステップへ移行しているように見せることが可能です。
3. 特殊な終了コードを持つコマンドへの対処
一部のコマンド(特に外部ツールや robocopy など)は、正常終了であっても「0」以外の数値を返すことがあります。
一般的なバッチ処理では「0以外 = 異常終了」とみなされるため、後続の判定処理で問題になることがあります。
このような場合、exit /b 0 を活用したり、ダミーの処理を挟むことでエラーレベルを強制的にリセットする手法があります。
@echo off
rem 失敗してもエラーレベルを強制的に 0 に見せかける例
command_that_might_fail || (echo 失敗を検知しましたが無視します & ver >NUL)
echo 現在のエラーレベル: %ERRORLEVEL%
ver >NUL は、常に成功するコマンドを実行することで %ERRORLEVEL% を 0 に上書きするテクニックです。
ERRORLEVEL を用いた高度なエラーハンドリング
エラーを単に無視するのではなく、「エラーが起きても停止はしないが、ログには残す」といった柔軟な対応が必要な場面もあります。
ここで重要になるのが ERRORLEVEL の制御です。
IF文による条件分岐
コマンドの実行直後にその結果を判定し、処理を分けるのがバッチファイルの定石です。
@echo off
echo バックアップを開始します...
copy C:\data\important.dat D:\backup\ 2>NUL
if %ERRORLEVEL% neq 0 (
echo 警告:ファイルのコピーに失敗しました。処理を継続します。
) else (
echo コピーは正常に完了しました。
)
echo ログの圧縮処理に移行します...
if %ERRORLEVEL% neq 0 は「終了コードが0ではない(=失敗)場合」という条件です。
ここで pause や exit を記述しなければ、バッチファイルは止まることなく次の「ログの圧縮処理」へと進みます。
遅延環境変数の展開が必要なケース
FOR 文などのループ処理の中でエラーチェックを行いながら連続実行する場合、通常の %ERRORLEVEL% では正しく値を取得できないことがあります。
これは、バッチファイルが解析されるタイミングの問題です。
ループ内でエラーを無視しつつ判定を行うには、遅延環境変数の展開を有効にします。
@echo off
setlocal enabledelayedexpansion
for %%f in (file1.txt file2.txt file3.txt) do (
copy %%f D:\backup\ >NUL 2>&1
if !ERRORLEVEL! neq 0 (
echo %%f の処理でエラーが発生しましたが、次のファイルへ進みます。
)
)
echo すべてのループ処理が終了しました。
endlocal
この方法を使えば、大量のファイル処理中に一部でエラーが発生しても、ループを中断させずに最後まで完走させることができます。
バッチ処理を中断させないための注意点とコツ
コマンドプロンプトの設計上、エラーを無視しようとしても、予期せぬ理由で処理が止まってしまうことがあります。
これを防ぐためのポイントをいくつか挙げます。
CALL コマンドの使用
別のバッチファイルを呼び出す際、単にバッチファイル名を記述すると、呼び出し先の処理が終わった時点で呼び出し元の処理まで終了してしまいます。これを防ぎ、呼び出し先のエラーに関わらず戻ってくるためには必ず CALL を使用します。
@echo off
echo 外部スクリプトを実行します。
rem CALLを使わないと、sub_process.bat 終了時にこのバッチも終わってしまう
call sub_process.bat
echo 外部スクリプトの成否に関わらず、この行は実行されます。
入力待ち(プロンプト)の回避
エラーを無視して連続実行したい場合、コマンドが「上書きしますか? (Y/N)」といった確認を求めて止まってしまう(対話モード)ことも避けるべきです。
多くのコマンドには、確認をスキップするオプションが用意されています。
del /q(静止モードで削除)xcopy /y(同名ファイルがある場合に強制上書き)echo f | xcopy source destination(パイプで応答を自動入力)
これらを適切に組み合わせることで、エラーや警告による「処理の停止」を物理的に回避できます。
実践例:メンテナンスバッチでの活用
以下に、複数のメンテナンス処理を連続して行い、個別のエラーを無視しつつ最終的なレポートを出すスクリプトの例を示します。
@echo off
set LOG_FILE=maintenance_log.txt
echo メンテナンス開始: %DATE% %TIME% > %LOG_FILE%
echo [1/3] 一時ファイルの削除中...
del /q /f %TEMP%\*.* 2>> %LOG_FILE% & echo 完了(またはスキップ)
echo [2/3] ディスクチェック(読み取り専用)...
chkdsk C: >NUL 2>> %LOG_FILE% & echo 完了
echo [3/3] ネットワークドライブの再接続...
net use Z: \\Server\Shared /user:guest "" >NUL 2>> %LOG_FILE% & echo 完了
echo すべての工程が終了しました。詳細は %LOG_FILE% を確認してください。
pause
このスクリプトでは、各ステップの末尾に & を配置し、さらに 2>> %LOG_FILE% を使ってエラーメッセージを画面に出さずログファイルに蓄積するようにしています。
これにより、ネットワークが切断されていて net use が失敗したとしても、全体の流れが止まることはありません。
まとめ
コマンドプロンプトでエラーを無視して連続実行を実現するには、演算子の使い分けとエラー出力のリダイレクトが鍵となります。
- 基本は
&演算子でコマンドを連結する。 - エラーを画面に出したくない場合は
2>NULを活用する。 - ループ内や複雑な判定には遅延環境変数の展開(
!ERRORLEVEL!)を用いる。 - 外部バッチの呼び出しには必ず
CALLを付ける。
エラーを完全に無視することは、開発段階ではバグを見落とすリスクにもなります。
しかし、安定稼働が求められる運用フェーズにおいては、「特定のエラーを想定した上で、止まらない仕組みを作る」ことが運用の効率化に直結します。
本記事で紹介したテクニックを駆使して、より堅牢で止まらないバッチ処理を構築してみてください。
