バッチファイルでファイルをコピー・バックアップするなら、ROBOCOPY(Robust File Copy)が最強のコマンドです。
xcopy では実現できなかったミラーリング・差分コピー・リトライ・詳細ログがすべて標準搭載されており、Windows Vista 以降のすべての Windows に同梱されています。
この記事では、基本構文から主要オプション・実務テンプレートまで ROBOCOPY を完全解説します。
ROBOCOPYとは(xcopとの違い)
ROBOCOPY は Microsoft が開発した高機能ファイルコピーツールです。xcopy と比較すると、以下のような明確な違いがあります。
| 機能 |
xcopy |
ROBOCOPY |
| ミラーリング(削除も同期) |
× |
○(/MIR) |
| 差分コピー(更新ファイルのみ) |
△(/D) |
○(/XO) |
| リトライ回数指定 |
× |
○(/R /W) |
| ログファイル出力 |
× |
○(/LOG /TEE) |
| 特定フォルダ・拡張子の除外 |
△ |
○(/XD /XF) |
| 詳細な終了コード |
× |
○(0〜16) |
| 搭載OS |
Windows 95〜 |
Windows Vista〜 |
ポイント:新規開発のバッチでは xcopy は使わず、最初から ROBOCOPY を選択することをおすすめします。コード量はほぼ同じですが、信頼性と機能が大幅に向上します。
基本構文
ROBOCOPY の基本構文は以下のとおりです。
構文
ROBOCOPY 送り元 送り先 [ファイルパターン] [オプション]
- 送り元:コピー元のフォルダパス
- 送り先:コピー先のフォルダパス
- ファイルパターン(省略可):
*.txt など。省略すると全ファイルが対象
- オプション:後述の各種フラグ
主要オプション一覧
| オプション |
説明 |
/E |
サブディレクトリを含む(空フォルダも対象) |
/S |
サブディレクトリを含む(空フォルダは除外) |
/MIR |
ミラーリング(送り先の余分なファイルを削除)。/E と /PURGE の組み合わせ |
/MOV |
ファイルを移動(コピー後に送り元のファイルを削除) |
/MOVE |
ファイルとディレクトリを移動 |
/XO |
送り先より古いファイルを除外(新しいファイルのみコピー) |
/XN |
送り先より新しいファイルを除外 |
/XC |
更新されたファイルを除外(同名で更新日時が異なるもの) |
/XD フォルダ |
指定フォルダを除外(スペース区切りで複数指定可) |
/XF ファイル |
指定ファイル(ワイルドカード可)を除外 |
/LOG:ファイル |
ログをファイルに出力(上書き) |
/LOG+:ファイル |
ログをファイルに追記 |
/TEE |
ログファイルと画面の両方に出力(/LOG と併用) |
/R:n |
コピー失敗時のリトライ回数(デフォルト100万回) |
/W:n |
リトライ間隔(秒)(デフォルト30秒) |
/NP |
進捗率(%)の表示を抑制 |
/NFL |
ファイル名のログ出力を抑制 |
/NDL |
ディレクトリ名のログ出力を抑制 |
基本のコピーサンプル
ファイルを1ファイルだけコピー
single-file-copy.bat
@echo off
:: 1ファイルをコピー(フォルダ指定で特定ファイルを対象にする)
ROBOCOPY C:Source D:Dest report.xlsx /R:3 /W:5
echo 完了
フォルダごとコピー(サブフォルダ含む)
folder-copy.bat
@echo off
setlocal
set SRC=C:ProjectsMyApp
set DST=D:BackupMyApp
:: /E でサブフォルダと空フォルダも含めてコピー
ROBOCOPY "%SRC%" "%DST%" /E /R:3 /W:5 /NP
echo フォルダコピー完了
endlocal
ミラーリング(/MIR)―削除も同期する完全ミラー
/MIR オプションを使うと、送り元と送り先を完全に同一の状態にします。送り元で削除したファイルは送り先でも削除されます。
注意:/MIR は送り先の余分なファイルを削除します。送り先に独自ファイルがある場合は失われます。初めて実行する前に必ず内容を確認してください。
mirror-sync.bat
@echo off
setlocal
set SRC=C:ProductionWeb
set DST=D:StagingWeb
:: /MIR = /E + /PURGE(送り先にない余分なファイルを削除)
ROBOCOPY "%SRC%" "%DST%" /MIR /R:3 /W:5 /NP /LOG:mirror.log /TEE
echo ミラーリング完了
endlocal
差分コピー(/XO)―新しいファイルだけコピー
/XO(eXclude Older)は、送り先のファイルより古い(または同じ)送り元ファイルをスキップします。実質的に「更新されたファイルだけコピー」する差分コピーになります。
incremental-backup.bat
@echo off
setlocal
set SRC=C:DataDocuments
set DST=D:BackupDocuments
:: /XO で送り先より古いファイルをスキップ(新しいファイルだけコピー)
ROBOCOPY "%SRC%" "%DST%" /E /XO /R:3 /W:5 /NP
echo 差分コピー完了
endlocal
除外設定(特定フォルダ・拡張子を除外)
/XD でフォルダを、/XF でファイルを除外できます。複数指定する場合はスペースで区切ります。
exclude-sample.bat
@echo off
setlocal
set SRC=C:ProjectsMyApp
set DST=D:BackupMyApp
:: node_modules と .git フォルダを除外、一時ファイルも除外
ROBOCOPY "%SRC%" "%DST%" /E /R:3 /W:5 /NP ^
/XD node_modules .git dist .cache ^
/XF *.tmp *.log *.bak
echo 除外コピー完了
endlocal
ログファイルへの出力(/LOG・/TEE)
バッチを自動実行する場合はログが必須です。/LOG でファイルに出力し、/TEE を追加すると画面にも同時表示できます。
log-output.bat
@echo off
setlocal
:: 日付をログファイル名に含める
set TODAY=%date:~0,4%%date:~5,2%%date:~8,2%
set LOGFILE=D:Logsackup_%TODAY%.log
ROBOCOPY C:Source D:Dest ^
/E /R:3 /W:5 /NP ^
/LOG+:"%LOGFILE%" ^
/TEE
echo ログ出力先: %LOGFILE%
endlocal
補足:/LOG: は上書き、/LOG+: は追記です。毎日バックアップする場合は /LOG+: でひとつのログファイルに追記していくか、日付をファイル名に含めて日別ログにするのが一般的です。
実務テンプレート集
毎日バックアップ(タスクスケジューラ連携)
daily-backup.bat
@echo off
setlocal
set TODAY=%date:~0,4%%date:~5,2%%date:~8,2%
set SRC=C:DataImportant
set DST=D:DailyBackup\%TODAY%
set LOG=D:Logsackup_%TODAY%.log
ROBOCOPY "%SRC%" "%DST%" /E /R:3 /W:10 /NP /LOG:"%LOG%" /TEE
:: 終了コードが8以上(コピー失敗)ならエラー通知
if %ERRORLEVEL% GEQ 8 (
echo エラー発生: ERRORLEVEL=%ERRORLEVEL% >> "%LOG%"
exit /b 1
)
endlocal
本番→ステージング同期
prod-to-staging.bat
@echo off
setlocal
set PROD=\\prod-serversharewebapp
set STAG=C:Stagingwebapp
:: /MIR で完全同期(ステージングを本番と同じ状態に)
:: /XD で一時フォルダとキャッシュを除外
ROBOCOPY "%PROD%" "%STAG%" ^
/MIR /R:5 /W:10 /NP ^
/XD tmp cache logs .git ^
/LOG+:sync.log /TEE
endlocal
ネットワーク越しの安定コピー
network-copy.bat
@echo off
setlocal
:: ネットワーク越しのコピーはリトライを多めに設定
:: /IPG:間隔ms でパケット間隔を指定してネットワーク帯域を節約
ROBOCOPY \\fileserverdata C:LocalCopy ^
/E /R:10 /W:30 /NP /IPG:10 ^
/LOG+:netcopy.log /TEE
endlocal
終了コードの一覧
ROBOCOPY の終了コード(ERRORLEVEL)は他のコマンドと異なり、0 以外でも正常終了する場合があります。ビット演算の組み合わせで意味が変わります。
| 終了コード |
意味 |
正常/異常 |
0 |
コピーなし(ファイルに差分なし) |
正常 |
1 |
1つ以上のファイルが正常にコピーされた |
正常 |
2 |
送り先に余分なファイルあり(/PURGE 未使用時) |
正常 |
4 |
ミスマッチファイルが存在 |
要確認 |
8 |
コピー失敗(いくつかのファイルがコピーされなかった) |
異常 |
16 |
致命的エラー(コピー未実施) |
異常 |
補足:エラー判定には IF %ERRORLEVEL% GEQ 8 を使います。タスクスケジューラでは ROBOCOPY の終了コードをエラーと判定しないよう、終了コードが 7 以下なら EXIT /B 0 を明示的に実行するのが実務上の定石です。
よくある失敗例と対処法
| 問題 |
原因・対処法 |
| タスクスケジューラでエラーになる |
ERRORLEVEL が 1 でもエラー扱いされる。バッチ末尾に IF %ERRORLEVEL% LEQ 7 EXIT /B 0 を追加 |
| /MIR で意図しないファイルが削除された |
初回は /L(リストのみ・実行なし)で事前確認してから実行する |
| ネットワークコピーが途中で止まる |
/R:10 /W:30 でリトライを増やす。/IPG で帯域を絞る |
| ログが文字化けする |
/UNILOG: を使うと Unicode(UTF-16)でログ出力される |
| パスにスペースが含まれてエラー |
送り元・送り先のパスを必ずダブルクォートで囲む |
FAQ
❓ ROBOCOPYとxcopyはどちらを使うべきですか? (クリックで開閉)
新規のバッチ開発では ROBOCOPY を使うことをおすすめします。Windows Vista 以降に標準搭載されており、リトライ・ミラーリング・詳細ログなど xcopy にはない機能が揃っています。既存のスクリプトで xcopy を使っている場合も、段階的に ROBOCOPY へ移行するとメンテナンスが楽になります。
❓ /MIR 実行前に削除対象を確認する方法はありますか? (クリックで開閉)
/L(List Only)オプションを付けると、実際のコピー・削除を行わずに対象ファイルのリストだけを表示できます。ROBOCOPY src dst /MIR /L でドライランし、内容を確認してから本番実行するのが安全です。
❓ ログが大きくなりすぎた場合の対処法は? (クリックで開閉)
/NFL(No File List)と /NDL(No Directory List)を組み合わせると、個別ファイル名の記録を省いてログサイズを大幅に削減できます。サマリー情報(コピー件数・スキップ件数・エラー件数)は引き続き記録されるため、結果の把握には十分です。