コンテンツへスキップ

ロボコピー(ROBOCOPY)でバックアップするときの覚書

こんな感じの要件を満たしたい。

ロボコピー(ROBOCOPY)でバックアップする。

Robocopy

rpbocopy を使ってみました。

ちなみに「ロバストコピー」って言う、言われ方もあるらしい。猛者向け?

robocopy

コマンドの構文

ROBOCOPY コピー元 コピー先 [ファイル [ファイル]…] [オプション]

ファイルを指定しなければ、フォルダがコピーの対象になる。
※目的のフォルダへのパスに空のフォルダ(ファイルが含まれない)があると、コピーされずに止まるので「/e」オプション(空のフォルダもコピーする)を指定する。

個人的によく使うサンプル

robocopy^
 "<Source directory>"^
 "<Target directory>"^
 /log:"<logfile path>"^
 /e /r:3 /w:3 /np /tee /z
robocopy^
 "<Source directory>"^
 "<Target directory>"^
 /log:"<logfile path>"^
 /e /r:3 /w:3 /np /mt /z

オプション

よく使っているものをヘルプから抜粋。

/E
:: 空のディレクトリを含むサブディレクトリをコピーします。
(とりあえず、これ。)

/PURGE
:: 既にコピー元に存在しないコピー先のファイル/ディレクトリを削除します。

/MIR
:: ディレクトリ ツリーをミラー化します (/E および /PURGE と同等)。
(どちらかというと、/L オプションでフォルダ間の比較に使用したりすることが多いかも。)

/L
:: リストのみ – いずれのファイルにも、コピー、タイムスタンプの追加、または削除を実施しません。

/R:n
:: 失敗したコピーに対する再試行数: 既定値は 1,000,000。
/W:n
:: 再試行と再試行の間の待機時間: 既定値は、30 秒です。

/NP
:: 進行状況なし – コピーの完了率を表示しません。

/LOG:ファイル
:: ログ ファイルに状態を出力します (既存のログを上書きします)。
/LOG+:ファイル
:: ログ ファイルに状態を出力します (既存のログ ファイルに追加します)。

/TEE
:: コンソール ウィンドウとログ ファイルに出力します。

/Z
:: 再起動可能モードでファイルをコピーします。
(途中で止まっても、再開すると続きから再開してくれる。さすがにファイル単位でだと思うけど。)

/MT[:n]
:: n 個のスレッドのマルチスレッド コピーを実行します (既定値 8)。
n は 1 から 128 までの値である必要があります。
このオプションは、/IPG および /EFSRAW オプションと互換性がありません。
パフォーマンス向上のため、/LOG オプションを使用して出力をリダイレクトします。

フォルダを除外するオプション

/XD ” フォルダ名 ”

例:ユーザーフォルダ丸ごとバックアップ。でも「OneDrive」のフォルダは除外する。

D:\>robocopy C:\Users\unimoni unimoni_221128_3510 /r:0 /w:0 /mir /xd "OneDrive" /log:D:\copy.log

ローカル環境でテスト

robocopy <source> <destination> <file> [<options>]

robocopy^
 "C:\Users\Administrator\Desktop\wallpapers"^
 "C:\Users\Administrator\Desktop\test"^
 "wallpaperbetter - 2021-04-27T213837.237.jpg"

wallpapers フォルダ → test フォルダへ「wallpaperbetter – 2021-04-27T213837.237.jpg」ファイルをコピーする。(オプション指定は無し。)

図1: コマンドプロンプトで robocopy コマンドを実行した結果。wallpapers フォルダから test フォルダへファイルを1件コピーし、ディレクトリ・ファイル・バイトの集計が「合計/コピー済み」で表示されている。
図1: コマンドプロンプトで robocopy コマンドを実行した結果。wallpapers フォルダから test フォルダへファイルを1件コピーし、ディレクトリ・ファイル・バイトの集計が「合計/コピー済み」で表示されている。

ネットワーク経由でコピーする為の準備。

お互いにHOSTS ファイルに相手のIP を記述して、名前解決できるように設定する。

ソースサーバー

図2: ソースサーバー側の hosts ファイルを Notepad++ で編集している画面。「192.168.56.181 wc1103.co.jp」「192.168.56.111 wc1202.co.jp」のIPアドレスとホスト名のマッピングが追加されている。
図2: ソースサーバー側の hosts ファイルを Notepad++ で編集している画面。「192.168.56.181 wc1103.co.jp」「192.168.56.111 wc1202.co.jp」のIPアドレスとホスト名のマッピングが追加されている。

ターゲットサーバー

図3: ターゲットサーバー側の hosts ファイルを編集している画面。同じくソースサーバー側のIPアドレスとホスト名のマッピングが追加されている。
図3: ターゲットサーバー側の hosts ファイルを編集している画面。同じくソースサーバー側のIPアドレスとホスト名のマッピングが追加されている。

ターゲットサーバー側で、コピー先のフォルダに共有をかけておく。
(共有するロールなどを指定してアクセス権を設定する。)
C ドライブとかに共有設定してもいいと思います。

図4: コピー先フォルダ「test」のプロパティ「共有」タブ。ネットワークパスでの共有が設定され、「ユーザーのフォルダーは共有されています。」という確認画面が表示されている。
図4: コピー先フォルダ「test」のプロパティ「共有」タブ。ネットワークパスでの共有が設定され、「ユーザーのフォルダーは共有されています。」という確認画面が表示されている。

ソースサーバーからアクセスできる。

図5: エクスプローラーでネットワーク経由(wc1202.co.jp)から共有フォルダ「test」にアクセスできている画面。
図5: エクスプローラーでネットワーク経由(wc1202.co.jp)から共有フォルダ「test」にアクセスできている画面。

サーバー間でコピー

丸ごと同期なので、/mir で。あとログ出力も設定した。

ファースト書き込みについては、いきなり「/mir」を使用して指定が反対だったりしたら、全部消えるので「/e」の方が安全。バックアップとかとってる環境じゃないとなかなか怖いっす。
また「/l」でテストできるので、テストもした方がいい。

攻めてる版 ^^;

robocopy^
 "C:\Users\Administrator\Desktop\wallpapers"^
 "\\wc1202.co.jp\test"^
 /w:0 /r:0^
 /mir^
 /zb^
 /log:test.log

安心版 ^^

robocopy^
 "C:\Users\Administrator\Desktop\wallpapers"^
 "\\wc1202.co.jp\test"^
 /w:0 /r:0^
 /e^
 /zb^
 /log:test.log
図6: コマンドプロンプトで /mir オプション付きの robocopy コマンドを実行し、ログファイル「test.log」に出力する設定で処理が完了した画面。
図6: コマンドプロンプトで /mir オプション付きの robocopy コマンドを実行し、ログファイル「test.log」に出力する設定で処理が完了した画面。

コピーできてる

図7: コピー先の test フォルダの中身。wallpaperbetter から始まる多数の画像ファイルがコピーされていることが確認できる。
図7: コピー先の test フォルダの中身。wallpaperbetter から始まる多数の画像ファイルがコピーされていることが確認できる。

コピーを実行した時に認証で引っかかるようなら、
robocopy を実行する前に(そのコマンドプロンプトで)「net use」を実行して、認証が済んだ状態にしておく。

エラー例:

エラー 1326 (0x0000052E) コピー元のファイル システムの種類を取得しています \\***\
ユーザー名またはパスワードが正しくありません。

net use を実行して認証してからrobocopy を実行する。

net use "コピー先(またはコピー元)" /user:権限のあるユーザー パスワード
図8: net use で認証を済ませた後に robocopy を実行したログ。「*EXTRA Dir」としてコピー先にのみ存在するフォルダが一覧表示されている。
図8: net use で認証を済ませた後に robocopy を実行したログ。「*EXTRA Dir」としてコピー先にのみ存在するフォルダが一覧表示されている。

参考:robocopyでユーザIDとパスワードが必要な共有フォルダに接続する方法

ログもイイ感じ。
(/np で進捗% を非表示にできます。結構細かく進捗を返すので、大きいファイルだと無駄なログの塊になるので注意。)

図9: Notepad++ で開いた test.log ファイル。「新しいファイル」としてコピーされたファイルと、その進捗%が記録されている。
図9: Notepad++ で開いた test.log ファイル。「新しいファイル」としてコピーされたファイルと、その進捗%が記録されている。
図10: 同じ test.log ファイルの末尾部分。ディレクトリ・ファイル・バイト・時刻ごとの「合計」「コピー済み」「スキップ」「不一致」「失敗」「Extras」の集計結果が表示されている。
図10: 同じ test.log ファイルの末尾部分。ディレクトリ・ファイル・バイト・時刻ごとの「合計」「コピー済み」「スキップ」「不一致」「失敗」「Extras」の集計結果が表示されている。

バッチファイル内で日本語やスペースの入ったパスを扱う場合。

パスを現在のディレクトリパスを「set CURDIR=%~dp0」で拾ってコピー元パスを生成してから、コピー先も変数とか使って定義する場合、パスに日本語やスペースが入っていると、robocopy がちゃんと認識してくれない問題。

とりあえずパスを「”(ダブルクォーテーション)」で括れば、日本語もスペースもいいんだけど、変数自体に「”」を持たせておいた方がよさそうです。

あと、最後の「\」を変数にいれてしまうと、最後の「”」がrobocopy の中でエスケープされるみたいなので、最後の「\」なしで、変数に「”」を入れましょう。
「\」を入れるとフォルダを指してくれるので、便利ですが無理そうです。パス自体に「”」を入れると、それ以上は伸ばせないので、順番も考えないとです。

バッチファイルのサンプル
:: 変数からパスを生成
set SD_D1="%CURDIR%Data\D1"
set SD_D2="%CURDIR%Data\D2"
set SD_D3="%CURDIR%Data\D3"
set TD_D1="%folder_name%\%version%\data"
set TD_D2="%folder_name%\%version%\database"
set TD_D3="%folder_name%\%version%\configuration"

:: フォルダパスが存在するか確認。
if not exist %SD_D1% (echo [NG] SD_D1=%SD_D1% & set ERR=1) else (echo [OK] SD_D1=%SD_D1% )
if not exist %SD_D2% (echo [NG] SD_D2=%SD_D2% & set ERR=1) else (echo [OK] SD_D2=%SD_D2% )
if not exist %SD_D3% (echo [NG] SD_D3=%SD_D3% & set ERR=1) else (echo [OK] SD_D3=%SD_D3% )
if not exist %TD_D1% (echo [NG] TD_D1=%TD_D1% & set ERR=1) else (echo [OK] TD_D1=%TD_D1% )
if not exist %TD_D2% (echo [NG] TD_D2=%TD_D2% & set ERR=1) else (echo [OK] TD_D2=%TD_D2% )
if not exist %TD_D3% (echo [NG] TD_D3=%TD_D3% & set ERR=1) else (echo [OK] TD_D3=%TD_D3% )

:: コピー実行。
robocopy %SD_D1% %TD_D1% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"
robocopy %SD_D2% %TD_D2% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"
robocopy %SD_D3% %TD_D3% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"

ちなみに最初は、robocopy の変数の方に「”」をつけてたんですが、開始側の「”」が消えるという変な現象が起きてめちゃくちゃはまりました。

ログについて

/tee をつけると、ログファイルへの書き込みつつ、コマンドプロンプトでも表示されます。
/L オプションでプレビュー、ログ書き込みのみ。

お世辞にもわかりやすいログとは言えないが、ないよりマシ。
欲を言えば、コマンドプロンプトで進捗インジケーターつけてほしい。

新しいファイル、新しいフォルダ

ソースと比べてターゲットが古い。または、ターゲットに存在しない。

図11: robocopy のログの一部。「新しいファイル」の項目として「delete file.txt」というファイルがコピー対象になっている例が表示されている。
図11: robocopy のログの一部。「新しいファイル」の項目として「delete file.txt」というファイルがコピー対象になっている例が表示されている。

コピー元、コピー先に存在するファイルで、ソースの方が古い場合は、「古い」になります。

どちらにせよ、差分はコピーされる。
(100% なんでも上書きにするなら、/is /it のオプションも追加する。)

コピー元にないが、コピー先にある。余計?なファイル。

「*EXTRA~」はコピー元にないが、コピー先にあるアイテムを指しているので、
オプションが「/E」か、「/MIR」かで振る舞いが変わってきます。

図12: robocopy のログの一部。「*EXTRA File」として、コピー元にはないがコピー先に存在するファイル「delete file.txt」が表示されている。
図12: robocopy のログの一部。「*EXTRA File」として、コピー元にはないがコピー先に存在するファイル「delete file.txt」が表示されている。

下記の表記は、先頭の数字がファイル数で、後ろがそのパス。

図13: robocopy のログのディレクトリ一覧部分。各行の先頭にある数字がそのディレクトリ内のファイル数を表しており、「7 C:\Users\unimoni\AppData\Local\AMD\CN\」のような形式になっている。
図13: robocopy のログのディレクトリ一覧部分。各行の先頭にある数字がそのディレクトリ内のファイル数を表しており、「7 C:\Users\unimoni\AppData\Local\AMD\CN\」のような形式になっている。
7	C:\Users\unimoni\AppData\Local\AMD\CN\

図14: エクスプローラーで実際に「AMD」>「CN」フォルダの中身を開いた画面。ログに表示されていたファイル数(7個)に対応する内容が確認できる。
図14: エクスプローラーで実際に「AMD」>「CN」フォルダの中身を開いた画面。ログに表示されていたファイル数(7個)に対応する内容が確認できる。

エラーになったとき

日本語の場合、「エラー」で検索。
「失敗」の項目が0 でないときも、ログから問題があったファイルを確認できます。

図15: robocopy のエラーログ。「エラー 5 (0x00000005) コピー先ディレクトリにタイムスタンプを追加しています...アクセスが拒否されました。」というエラーメッセージが複数のフォルダに対して表示されている。
図15: robocopy のエラーログ。「エラー 5 (0x00000005) コピー先ディレクトリにタイムスタンプを追加しています…アクセスが拒否されました。」というエラーメッセージが複数のフォルダに対して表示されている。

最終結果一覧の数字がズレている件

ズレているのは英語表記にするといいらしい。

Code Page Identifiers

chcp 65001
図16: robocopy の実行結果の最終集計表。Dirs(ディレクトリ)・Files(ファイル)・Bytes(バイト)・Times(時刻)ごとに、Total・Copied・Skipped・Mismatch・FAILED・Extras の件数が一覧表示されている。
図16: robocopy の実行結果の最終集計表。Dirs(ディレクトリ)・Files(ファイル)・Bytes(バイト)・Times(時刻)ごとに、Total・Copied・Skipped・Mismatch・FAILED・Extras の件数が一覧表示されている。

ただ、英語読めないと、何が起きているかもわからないという。

Robocopy /MIR ログ一覧(日本語・英語対応)

Robocopy /MIR ログ一覧(日本語・英語対応)

コパイロットさんイメージ画
日本語表示英語表示意味コピー元コピー先/MIR の動作
新しいファイルNew Fileコピー元にだけ存在するファイル○×コピー
変更ありChangedサイズ・日時などが異なる○○コピー
同一Same同じファイルと判定○○スキップ
古いOlderコピー先の方が古い○○通常はコピー
新しいNewerコピー先の方が新しい○○条件によってはスキップ
*EXTRA File*EXTRA Fileコピー先にだけ存在するファイル×○削除
*EXTRA Dir*EXTRA Dirコピー先にだけ存在するフォルダ×○削除
LonelyLonelyコピー元にだけ存在するファイル(比較時等)○×条件による

/MIRで実際に処理されるもの

表示動作
新しいファイル / New Fileコピー
変更あり / Changed上書きコピー
古い / Older上書きコピー
同一 / Sameスキップ
*EXTRA File削除
*EXTRA Dir削除

障害解析用の覚え方

ログ表示判定
New File / 新しいファイル転送された
Changed / 変更あり転送された
Older / 古い転送された可能性大
Same / 同一転送されていない
*EXTRA File削除対象
*EXTRA Dir削除対象

つまり、/MIR のログで 「新しいファイル」「変更あり」 が出ていれば、そのファイルは Robocopy が差分として認識して転送対象にしています。逆に 「同一」 ならスキップです。

robocopy を中断すると、属性が「システム保護」のままになることがある

robocopy を中断したときに、「システムで保護」の属性が付いてしまう。

隠しファイルよりもさらに強い状態で、エクスプローラーで「隠しファイルを表示する」をONにしても出てこず、「保護されたオペレーティング システム ファイルを表示しない(推奨)」のチェックも外さないと見えない。原因は、robocopy の既定の /COPY:DAT(データ・属性・タイムスタンプ)がコピー元の属性をそのままコピー先に反映する仕様と、/Z の再開処理が絡んでいるっぽい。再開した回でサイズや日時が「既に同じ」と判定されてスキップされたファイル・フォルダは、属性をクリアする最後の処理まで走らないことがあるらしく、システム+隠し属性がコピー先に残ってしまうことがある。

図41: エクスプローラーで対象の「vmware」フォルダを確認した画面。この時点では属性がシステム保護のままになっている。

attrib コマンドで属性を剥がせば直る。

attrib -s -h "G:\vmware" /s /d

念のため、attrib のヘルプ全文も載せておく。

C:\Windows\System32>attrib /?
ファイル属性を表示または変更します。

ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] [+O | -O] [+I | -I] [+X | -X] [+P | -P] [+U | -U]
       [ドライブ:][パス][ファイル名] [/S [/D]] [/L]

  +   属性を設定します。
  -   属性を解除します。
  R   読み取り専用ファイル属性。
  A   アーカイブ ファイル属性。
  S   システム ファイル属性。
  H   隠しファイル属性。
  O   オフライン属性。
  I   非インデックス対象ファイル属性。
  X   スクラブ ファイルなし属性。
  V   整合性属性。
  P   固定属性。
  U   固定解除属性。
  B   SMR BLOB 属性。
  [ドライブ:][パス][ファイル名]
      attrib で処理するファイルを指定します。
  /S  現在のフォルダーとすべてのサブフォルダーの一致するファイルを
      処理します。
  /D  フォルダーも処理します。
  /L  Symbolic Link のターゲットに対する Symbolic Link
      の属性で動作します
図42: attrib コマンドで属性を解除した後、同じフォルダをエクスプローラーで確認した画面。通常のフォルダとして表示されている。

属性を戻したら、通常のフォルダとして見えるようになった。

コピー時に /A-:SH を付けておくと、コピーしたファイルから隠し・システム属性を自動的に除去してくれるので、そもそもこの状態にならずに済む。

robocopy^
 "<Source directory>"^
 "<Target directory>"^
 /log:"<logfile path>"^
 /e /r:3 /w:3 /np /tee /z /a-:sh

参考:

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/robocopy

robocopy – 個人的によく使うオプションメモ

https://n-archives.net/software/robosync/articles/robosync-tips-option-l/

その他のファイル操作系のコマンド

copyX

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/copy

rmdir , rd

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/rmdir

削除

ディレクトリを削除します。

RMDIR [/S] [/Q] [ドライブ:]パス
RD [/S] [/Q] [ドライブ:]パス

    /S      指定されたディレクトリに加えて、そのディレクトリ内のすべての
            ディレクトリとファイルを削除します。ディレクトリ ツリーを削除
            するときに使用します。

    /Q      /S を指定してディレクトリ ツリーを削除するときに、確認の
            メッセージを表示しません。(QUIET モード)

ファイルだとdel

C:\Windows\system32>del /?
ファイル (複数可) を削除します。

DEL [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前
ERASE [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前

  名前          ファイルまたはディレクトリ (複数可) の一覧を指定します。
                複数のファイルを削除するときはワイルドカードを使用します。
                ディレクトリが指定されたときはディレクトリ内のすべてのファ
                イルは削除されます。

  /P            各ファイルを削除する前に確認のメッセージを表示します。
  /F            読み取り専用ファイルを強制的に削除します。
  /S            指定されたファイルをすべてのサブディレクトリから削除します。
  /Q            ワイルドカードを使用して一括削除するときに、確認のメッセージ
                を表示しません。(QUIET モード)
  /A            属性により削除するファイルを選択します。
  属性          R  読み取り専用            S  システム ファイル
                H  隠しファイル            A  アーカイブ
                I  非インデックス対象ファイル  L  再解析ポイント
                -  その属性以外

コマンド拡張機能を有効にすると、DEL と ERASE は次のように変更されます:

/S スイッチの表示形式が逆になり、見つからなかったファイルではなく
削除されたファイルだけが表示されるようになります。

rename

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/rename

C:\Windows\system32>rename /?
ファイル (複数可) の名前を変更します。

RENAME [ドライブ:][パス]ファイル名1 ファイル名2
REN [ドライブ:][パス]ファイル名1 ファイル名2

ファイル名2 には新しいドライブもパスも指定できないので注意してください。

以上です。

(Visited 9,101 times, 6 visits today)

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です