2024年2月14日水曜日

ROBOCOPYでファイルのバックアップをやろうとしたら色々嵌った話

どうも皆様ぐーてんもるげん!相変わらずPCに噛り付いている私です。
今回のネタはずばり「ROBOCOPY」。

調べたことを色々メモ書きにしてたんですが、鳥頭な私のことです、きっとそのうちメモごと無くして綺麗さっぱり忘れちゃうんじゃないか?と思い立ち、自分の備忘録も兼ねて今回記事にしてみることにしました。
 

注意!
本記事に記載した内容は不肖私のつたないPC知識で書いた内容ですので、検証不足な点や誤り等ある可能性が御座います。
可能な限り情報の正確性を心がけていますが、安全性や確実な情報提供を保証するものではありません。
当方では責任を負いかねますのでご了承ください。

では本編!!

ROBOCOPYって?

指定した二つのフォルダを同期させることで、ファイルやフォルダのバックアップ等に広く利用されているコマンドになります。
ちなみに、ROBOCOPYの正式名称は「Robust File Copy」で、直訳すると「堅固で確実なファイルコピー」。
「ロボットがコピーするからロボコピー」じゃないんですね。へぇ~。
堅固で確実なファイルコピーを提供すると銘打っているだけあって、そのあたりの機能はかなりリッチです。具体的には

・エラー発生時の再試行回数の制限と待ち時間を任意に設定可能
・ネットワーク越し(NASからのファイルコピーとか)を実施した際、何らかの理由でネットワーク接続が切断された場合、中断と再開が可能
・属性やセキュリティ設定もコピー可能
・MIRコマンドを使用すれば、コピー先にある余分なファイルを削除することも可能
・256文字を超える長いパスを処理できる
・動作ログを記録できる

とまぁ、ググればわらわら出てくるんですが、かなりの機能を有している訳です。
しかもこんなに使えるROBOCOPY、WinXP以降の環境であればサポートしているため、昨今世に出回っているWindows環境であれば、ほぼどこでも使えちゃう、環境に依存しにくいコマンドなのです。

と、ここまで書いといて「何でコマンドでやるわけ?フォルダ開いてコピペすればいいやーん」と思われた方、いらっしゃると思います。
でも考えてみてください。対象のファイルが5~6個とかならまだいいでしょうが、これが10~20、下手すりゃ100を超える場合、それを一個ずつ比較して、新しいファイルかどうかを確認して、更新されてたらコピーする。
それを毎日定期的にやれ、と言われたら???
数多の世界に存在するかもしれない、真性PCドM気質な方なら耐えられるかも知れませんが、特殊な訓練を受けていない我々からすれば、そらもう発狂ものですよね?
やってられるかこの野郎であり、ミスって悲惨な結果になって泣くことになってもおかしくありません。

要は手動でやるにはあまりに現実的でない、定期的なファイルコピーを自動で行う、そこでROBOCOPYが登場する訳です!


ROBOCOPYを使ってみる

ま、とりあえずやってみましょう!今回用意した環境は以下の通り。

・コピー元:C:\FROM
0001.txt
0002.txt
0003.txt が入っています。

・コピー先:C:\TO
該当フォルダはカラの状態です。

今回発行したコマンドは下記になります。


×
@ECHO OFF

REM カレントディレクトリを保持
SET CAL_DIR=%~dp0

REM カレントディレクトリに実行ログを出力するように設定
SET LOGFILE=%CAL_DIR%ROBOCOPY.log

REM 同期元
SET DATA_FROM="C:\from"

REM 同期先
SET DATA_TO="C:\to"

ROBOCOPY %DATA_FROM% %DATA_TO% /copy:DT /B /e /XO /R:1 /W:1 /NP /NC /NS /NDL /NFL /LOG+:%LOGFILE%	

注目頂きたいのはROBOCOPYの行。何やらやたらとごちゃごちゃ並んでます。
これがROBOCOPYのオプション設定。各パラメータに意味があり、これでROBOCOPYの動作を制御しています。

今回設定したオプションは以下の通りです。

%DATA_FROM% コピー元フォルダ
%DATA_TO% コピー先フォルダ
/copy:DT コピーフラグ。DTはそれぞれD=データ、T=タイムスタンプを示します。
本オプションを設定しないと、NAS等からのデータコピーでは高確率で失敗します。
今回の例ではA=属性情報(Attributes)をコピー対象から除外する事で、異なるファイルシステム間のファイルコピーを実現しています。
/B バックアップモードでファイルのコピーを試みます。
本オプションを付与することで、ROBOCOPYコマンドの実行ユーザに該当ファイルへのアクセス権が付与されていなかったとしても、コピーすることが可能になります。
※実行ユーザがAdministratorsグループか、Backup Operatorsグループのいずれかに所属している必要があります。
/e カレントディレクトだけでなく、サブフォルダも再帰的にコピーします。
類似するオプション「/s」と異なり、/eを指定した場合、サブフォルダが
空フォルダである場合であっても、コピー対象として扱います。
/XO コピー元ファイルがコピー先ファイルより古い場合、処理対象から除外されます。
/R:1 コピー時にエラーが発生した際の再試行回数を指定します。
本パラメータを設定しない場合、規定値で100万回のリトライを繰り返します。
/W:1 再試行時の待機時間を秒単位で指定します。
本パラメータを設定しない場合、規定値で30秒待機します。
/NP ログにコピー処理の進捗状況を出力しません。
本設定を入れておかないとログが非常に煩雑になり、読みにくくなります。
/NC コピー対象ファイルがコピーされる、コピーされない理由(ファイルクラス)をログに出力しません。
/NS コピー対象ファイルのサイズ情報をログに含めません。
/NDL ログにディレクトリ一覧情報を含めません。
/NFL ログにファイル一覧情報を含めません。
/LOG+:%LOGFILE% ログに処理状況を「追記モード」で出力します。

 

 実行結果はこんな感じですね。 


×
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2024年2月1日  9:57:50
   コピー元 : C:\FROM\
     コピー先 : C:\TO\

    ファイル: *.*
	    
  オプション: *.* /NS /NC /NDL /NFL /S /E /DCOPY:D /COPY:DT /B /NP /XO /R:1 /W:1 

------------------------------------------------------------------------------


------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:         1         0         1         0         0         0
     ファイル:         3         3         0         0         0         0
      バイト:     2.3 k     2.3 k         0         0         0         0
       時刻:   0:00:00   0:00:00                       0:00:00   0:00:00


       速度:              105913 バイト/秒
       速度:               6.060 MB/分
   終了: 2024年2月1日  9:57:50

無事、TOフォルダにFROMフォルダに入っていたテキスト3つがコピーされました。

検証1.コピー元フォルダの中身とコピー先フォルダの中身が完全一致だった場合

まぁ、これに関しては検証するまでもないですね。実行結果は以下の通りです。


×
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2024年2月1日 10:53:49
   コピー元 : C:\FROM\
     コピー先 : C:\TO\

    ファイル: *.*
	    
  オプション: *.* /NS /NC /NDL /NFL /S /E /DCOPY:D /COPY:DT /B /NP /XO /R:1 /W:1 

------------------------------------------------------------------------------


------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:         1         0         1         0         0         0
     ファイル:         3         0         3         0         0         0
      バイト:     2.3 k         0     2.3 k         0         0         0
       時刻:   0:00:00   0:00:00                       0:00:00   0:00:00
   終了: 2024年2月1日 10:53:49

一覧化するとこんな感じ。更新対象ファイルはひとつも無いので、何も変化しません。

DATA_FROMフォルダ(コピー元) DATA_TOフォルダ(コピー先) 結果
0001.txt
(2024/01/01)
0001.txt
(2024/01/01)
スキップ
0002.txt
(2024/01/05)
0002.txt
(2024/01/05)
スキップ
0003.txt
(2024/01/05)
0003.txt
(2024/01/05)
スキップ

検証2.コピー元フォルダ、コピー先フォルダに同じファイルがあり、かつコピー元の方が新しかった場合

これまた結果は非常にわかりやすいです。


×
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2024年2月1日 10:59:57
   コピー元 : C:\FROM\
     コピー先 : C:\TO\

    ファイル: *.*
	    
  オプション: *.* /NS /NC /NDL /NFL /S /E /DCOPY:D /COPY:DT /B /NP /XO /R:1 /W:1 

------------------------------------------------------------------------------


------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:         1         0         1         0         0         0
     ファイル:         3         1         2         0         0         0
      バイト:     2.3 k       543     1.8 k         0         0         0
       時刻:   0:00:00   0:00:00                       0:00:00   0:00:00


       速度:              108600 バイト/秒
       速度:               6.214 MB/分
   終了: 2024年2月1日 10:59:57

結果一覧はこんな感じです。
ここまではほぼ予想通りかと思います。次からが本題。

DATA_FROMフォルダ(コピー元) DATA_TOフォルダ(コピー先) 結果
0001.txt
(2024/01/01)
0001.txt
(2024/01/01)
スキップ
0002.txt
2024/01/10にファイル更新
0002.txt
(2024/01/10)
上書き
0003.txt
(2024/01/05)
0003.txt
(2024/01/05)
スキップ

検証3.コピー元フォルダにコピー先にあるファイルが無かった場合

では、コピー先には該当ファイルがあるのに、コピー元に該当ファイルが無かったらどうなるでしょう?

実行結果からどうぞ。


×
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2024年2月1日 11:03:50
   コピー元 : C:\FROM\
     コピー先 : C:\TO\

    ファイル: *.*
	    
  オプション: *.* /NS /NC /NDL /NFL /S /E /DCOPY:D /COPY:DT /B /NP /XO /R:1 /W:1 

------------------------------------------------------------------------------


------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:         1         0         1         0         0         0
     ファイル:         2         0         2         0         0         1
      バイト:     1.4 k         0     1.4 k         0         0       986
       時刻:   0:00:00   0:00:00                       0:00:00   0:00:00
   終了: 2024年2月1日 11:03:50

MIRオプションを付与したときと同様、Extrasとして計上されました。
ただし、Extrasにカウントアップはされますが、MIRオプションと違ってコピー先フォルダから該当ファイルは削除されません

DATA_FROMフォルダ(コピー元) DATA_TOフォルダ(コピー先) 結果
0001.txt
→削除
0001.txt
(2024/01/01)
変化なし
0002.txt
(2024/01/05)
0002.txt
(2024/01/05)
スキップ
0003.txt
(2024/01/05)
0003.txt
(2024/01/05)
スキップ

検証4.コピー元フォルダよりコピー先フォルダのファイルの方が新しかった場合

では最後、コピー先フォルダの資源の方が最近更新されてたらどうなるか。

×
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2024年2月1日 11:05:48
   コピー元 : C:\FROM\
     コピー先 : C:\TO\

    ファイル: *.*
	    
  オプション: *.* /NS /NC /NDL /NFL /S /E /DCOPY:D /COPY:DT /B /NP /XO /R:1 /W:1 

------------------------------------------------------------------------------


------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:         1         0         1         0         0         0
     ファイル:         3         0         3         0         0         0
      バイト:     2.3 k         0     2.3 k         0         0         0
       時刻:   0:00:00   0:00:00                       0:00:00   0:00:00
   終了: 2024年2月1日 11:05:48


何と何も変化しません。ROBOCOPYの仕様では原則として、新旧関係なくコピー元資源でコピー先資源を上書きするので意外だったのでは無いでしょうか。
理由は上記のオプション「/XO」。
これによりコピー元資源の方がコピー先資源より古い場合、処理対象から無視されます

DATA_FROMフォルダ(コピー元) DATA_TOフォルダ(コピー先) 結果
0001.txt
(2024/01/01)
0001.txt
(2024/01/01)
スキップ
0002.txt
(2024/01/05)
0002.txt
(2024/01/05)
スキップ
0003.txt
(2024/01/05)
0003.txt
2024/01/20に更新、コピー元より新しい
スキップ

他のオプションの設定とか、MIRオプションを設定した場合の動きとかを書き出すと、とんでもなく長くなるので、そのあたりに興味のある方は是非ググってみてください!

最後までお読みいただき有難う御座いました。

0 件のコメント:

コメントを投稿