本記事は、以下のような方を対象としています。
- 大量のファイルをコピーしたい、またはバックアップしたい。
- 大切なファイルなので、一つも破損して欲しくない。また、漏れなくコピーしたい。
- PCのOSは、MacまたはLinuxディストリビューション(Ubuntu、CentOS、RHELなど)。(※WindowsでもWSLを導入すれば本手順が実施できます。)
- PCローカル上でのコピー、またはリモートサーバとの間でのSSHコピーをしたい。
単にファイルをコピーするだけならGUI上でコピペすれば良いですが、大量のファイルをコピペすると以下のような弊害があります。
- 進捗が見えず、あとどのくらいかかるのかが分からない。
- 画面やアプリが固まる。
- コピーのプロセスが落ちて、どこまで完了したのか分からず、また最初から実行する羽目になる。
- 完了しても、ちゃんと全てのファイルが漏れなく破損なくコピーできたのか不安になる。
そこで、本記事では「rsync」コマンドを用いて、CLI(シェル)上で大量のファイルをコピーする手順をご紹介します。
結論:このコマンドを実行します。
大量のファイルを、漏れなく、破損なく、フォルダごとコピーし、その進捗を監視しつつ、プロセスが落ちても途中から再開できるシェルコマンドは、以下です。
rsync -avh --stats --info=progress2 --no-inc-recursive <コピー元のフォルダパス> <コピー先のフォルダパス>
次章に紹介する手順で、このコマンドを実行していきます。
手順
※本手順の動作確認環境は脚注[1]の通りです。
⓪事前準備
- シェルを立ち上げます。(Macの場合は「ターミナル」アプリを開きます。)
- (コピー時にファイルの所有者やアクセス権限を保持したい場合)以下のコマンドを実行し、管理者権限ユーザ(root)にログインします。元の一般権限ユーザのログインパスワードを求められたら、入力します。
sudo su -
- 以下のコマンドを実行し、本手順内でコマンドとして実行するrsyncのバージョンを確認します。
rsync --version
- 以下のコマンドを実行し、本手順内で実行するシェルスクリプトを作成します。(10行に渡りますが、一つのコマンドです。)
echo '#!'$SHELL'
echo "$(date '\''+%Y-%m-%d %H:%M:%S'\'') [INFO] $0 process started now."
if rsync -avh --stats --info=progress2 --no-inc-recursive $3 "$1" "$2"; then
echo "$(date '\''+%Y-%m-%d %H:%M:%S'\'') [INFO] $0 process successfully done!!"
else
echo "$(date '\''+%Y-%m-%d %H:%M:%S'\'') [ERROR] $0 process failed." 1>&2
fi
' > ./rsync_with_progress.sh
- 以下のコマンドを実行し、シェルスクリプトを実行できるように権限変更します。
chmod +x ./rsync_with_progress.sh
- 以下のコマンドを実行し、シェルスクリプトを作成したフォルダを確認してメモしておきます。
pwd
- (rsyncのバージョンが3.1.0未満の場合)以下のコマンドを実行し、シェルスクリプトの一部の文字列を置換します。
sed -i s/'--info=progress2 --no-inc-recursive'/--progress/ ./rsync_with_progress.sh
- (SSH経由でコピーする場合)以下のコマンドを実行し、シェルスクリプトの一部の文字列を置換します。
sed -i s/-avh/"-avhe 'ssh -o StrictHostKeyChecking=no<その他のsshコマンドオプション>'"/ ./rsync_with_progress.sh
- 「その他のsshコマンドオプション」が必要ない場合は指定しません。具体的には以下などがあります。
-p <リモートサーバのSSHポート番号>
: デフォルトの「22」であれば、指定は不要です。-i <秘密鍵のファイルパス>
: ログインの認証方式が鍵認証ではなくパスワード認証であれば、指定は不要です。
- 「その他のsshコマンドオプション」が必要ない場合は指定しません。具体的には以下などがあります。
- 作成したシェルスクリプトの内容は、以下のコマンドを実行することで確認できます。
cat ./rsync_with_progress.sh
- 次節以降の手順を実施する前に、コピー元とコピー先のフォルダを具体的に決めておきます(コピーした後にまた別の場所に移動する羽目にならないよう、よく検討して決めます)。
①フォルダのコピーを開始
rsyncに-a
オプションを付与した場合でも、タイムスタンプがコピー日時に更新された状態でコピーされる事象を確認しています(WebDAVでマウントしたフォルダにHTTPSを経由してコピーする場合など)。例えば動画データのタイムスタンプが更新されると、時系列情報がバラバラになってしまいます。
そういった不測の事態が起きないことを確認するためにも、まずは小さい規模でテストをしてから本番実施することをオススメします。
- シェルを立ち上げます。
- (コピー時にファイルの所有者やアクセス権限を保持したい場合※)以下のコマンドを実行し、管理者権限ユーザ(root)にログインします。元の一般権限ユーザのログインパスワードを求められたら、入力します。※「⓪事前準備」の項の2点目を参照。
sudo su -
- 以下のコマンドを実行し、このあと実行するrsyncが想定しているバージョンであるかどうかを改めて確認します。
rsync --version
- 以下のコマンドを実行し、シェルスクリプトのあるフォルダに移動します(「⓪事前準備」の項でメモしたフォルダパスを指定します)。
cd '<シェルスクリプトのあるフォルダパス>'
- 以下のコマンドを実行し、コピー元とコピー先のフォルダパスをそれぞれシェル変数に格納します。
COPY_SOURCE_PATH='<コピー元のフォルダパス>'
COPY_DESTINATION_PATH='<コピー先のフォルダパス>'
- 以下のコマンドを実行し、シェル変数に格納されたフォルダパスを表示して、間違いないか確認します。
echo "$COPY_SOURCE_PATH"
echo "$COPY_DESTINATION_PATH"
- 以下のコマンドを実行し、フォルダのコピーを開始します。
nohup \
./rsync_with_progress.sh "$COPY_SOURCE_PATH" "$COPY_DESTINATION_PATH" \
> ./rsync_$(date +%Y%m%dT%H%M%S).log \
2> ./rsync_error_$(date +%Y%m%dT%H%M%S).log \
&
- (SSH経由でのコピーの場合)リモートサーバへのログインのために、以下の手順でログインパスワードを入力します。公開鍵認証ができ、パスワードの入力が不要な場合は、実施不要です。
- 以下のコマンドを実行し、対象プロセスのジョブ番号を確認します。
jobs | grep rsync_with_progress
- 想定される出力内容は以下の通りです。(プロセスがパスワード入力待機状態のため「Stoppped」になっています。)
[<ジョブ番号>]+ Stopped nohup ./rsync_with_progress.sh "$COPY_SOURCE_PATH" "$COPY_DESTINATION_PATH" > ./rsync_$(date +%Y%m%dT%H%M%S).log 2> ./rsync_error_$(date +%Y%m%dT%H%M%S).log
- 想定される出力内容は以下の通りです。(プロセスがパスワード入力待機状態のため「Stoppped」になっています。)
- 以下のコマンドを実行し、対象のプロセスをバックグラウンド(裏)からフォアグラウンド(表)に一時的に移動します。
fg <対象プロセスのジョブ番号>
- 以下のようなパスワード入力プロンプトが表示されるので、ログインユーザに対応するパスワードを入力してEnterを押します。
<サーバ上のユーザ名>@<サーバのホスト名またはIPアドレス>'s password:
- Enter後に元のローカルPCのプロンプトに戻ってしまった場合は、何らかのエラーが発生していると思われるので、「②-i. 経過確認手順」の項を参照してエラー内容を確認します。
- Enter後に何も受け付けない状態になれば、正常にプロセスが進行しています。「Ctrl + Z」(Macの場合は「control + Z」)を入力して、一時的にプロセスを停止します。
- 以下のコマンドを実行し、対象のプロセスを再びバックグラウンドで実行再開します。
bg <対象プロセスのジョブ番号>
- 以下のコマンドを実行し、対象プロセスのジョブ番号を確認します。
- 以下のコマンドを実行し、ログファイルが2つ新規作成されていることを確認します。
ls -l rsync_????????T??????.log rsync_error_????????T??????.log
- スリープやシャットダウンをしてしまうと処理が停止してしまうので、自動スリープや自動シャットダウンがPCに設定されている場合は、停止しておきます。(コピーが完了し次第、忘れずに元に戻すことを覚えておきます。)
②フォルダのコピーの経過確認・中断・再開
②-i. 経過確認手順
ログファイルの中身を確認することで、コピーの経過を確認します。
- シェルを立ち上げます。
- (コピー時にファイルの所有者やアクセス権限を保持したい場合※)以下のコマンドを実行し、管理者権限ユーザ(root)にログインします。元の一般権限ユーザのログインパスワードを求められたら、入力します。※「⓪事前準備」の項の2点目を参照。
sudo su -
- 以下のコマンドを実行し、シェルスクリプトのあるフォルダに移動します(「⓪事前準備」の節でメモしたフォルダパスを指定します)。
cd '<シェルスクリプトのあるフォルダパス>'
- 以下のコマンドを実行し、ログファイル名を確認します。
ls -l rsync_????????T??????.log rsync_error_????????T??????.log
- 以下のコマンドを実行し、標準エラー出力のログファイルの中身を確認します。
cat rsync_error_<上で確認した日時を示す文字列>.log
- 何も表示されなければ問題ないですが、何らかのエラーがログファイルに書き込まれている場合は、エラー文や以下手順の標準出力のログファイルの内容を読んで対処し、その後「②-iii. (中断した場合)コピーの再開手順」の項を参照して再度コピーを実施してください。
- 以下のコマンドを実行し、標準出力のログファイルの中身を閲覧します。
tail -f rsync_<上で確認した日時を示す文字列>.log
出力例は以下の通りです(※rsyncのバージョンが3.1.0以上の場合)。進捗状況の読み方と残り時間の概算方法については、「[補足3] 表示されている進捗%から残りのコピー時間を推定できるか」の章を参照ください。
2025-04-04 21:00:05 [INFO] ./rsync_with_progress.sh process started now.
<中略>
2012/12/29/20121229-195544/IMG_0427.JPG <-- コピー中のファイルパス
25.79M 0% 928.38kB/s 0:00:27 (xfr#40, to-chk=45070/45125) <-- 進捗状況
2012/12/29/20121229-195544/IMG_0436.JPG
27.03M 0% 943.09kB/s 0:00:27 (xfr#41, to-chk=45069/45125)
<中略>
2025-04-04 23:10:07 [INFO] ./rsync_with_progress.sh process successfully done!!
②-ii. コピーの中断手順
何らかの理由でコピーを中断する必要が出た場合は、PCをそのままシャットダウンするか、以下の手順で実行中のプロセスを強制終了します。
- シェルを立ち上げます。
- 以下のコマンドを実行し、シェルスクリプトが実行されているプロセスのプロセスID(PID)を確認します。シェルスクリプトが複数のプロセスで並行して動いている場合は、複数のプロセスIDを確認します。
※ヘッダー行以外何も表示されない場合は、既にプロセスは停止しています。ps aux | grep -v grep | grep -e PID -e rsync_with_progress
- 以下のコマンドを実行し、シェルスクリプトのプロセスを強制終了します。パスワードの入力を求められるので、実行しているユーザのPCログインパスワードを入力します。シェルスクリプトが複数のプロセスで並行して動いている場合は、その全てについて強制終了します。
sudo kill -9 <対象のプロセスID>
- 以下のコマンドを実行し、ヘッダー行以外何も表示されないことを確認します。
ps aux | grep -v grep | grep -e PID -e rsync_with_progress
関係のないプロセスのプロセスIDを指定してしまうと、予期せずPCの重要なプロセスを強制終了してしまう恐れがあります。よく確認して、正しいプロセスIDを指定するように気をつけましょう。
②-iii. (中断した場合)コピーの再開手順
PCが予期せずシャットダウンするなどの理由で、コピーが中断した場合は、「①フォルダのコピーを開始」の節の手順を再度実行し直すことで、コピーを再開できます。その際、ログファイルは別の新規ファイルとして作成されます。
③フォルダのコピーの完了確認
コピーのシェルスクリプトが正常に完了したかどうかを確認します。
- シェルを立ち上げます。
- (コピー時にファイルの所有者やアクセス権限を保持したい場合※)以下のコマンドを実行し、管理者権限ユーザ(root)にログインします。元の一般権限ユーザのログインパスワードを求められたら、入力します。※「⓪事前準備」の項の2点目を参照。
sudo su -
- 以下のコマンドを実行し、シェルスクリプトが実行されているプロセスを確認します。
ps aux | grep -v grep | grep -e PID -e rsync_with_progress
- ヘッダー行以外に表示される場合は、プロセスが終了していないため、引き続きコピ-完了まで待機します。
- ヘッダー行以外に何も表示されない場合は、既にプロセスは停止しています。コピーが全て完了したか、一部失敗して完了したか、プロセスが中断された可能性があるので、いずれなのかを以下の手順で確認します。
- 以下のコマンドを実行し、シェルスクリプトのあるフォルダに移動します(「⓪事前準備」の節でメモしたフォルダパスを指定します)。
cd '<シェルスクリプトのあるフォルダパス>'
- 以下のコマンドを実行し、ログファイル名を確認します。
ls -l rsync_????????T??????.log rsync_error_????????T??????.log
- 以下のコマンドを実行し、標準出力のログファイルの中身から文字列「process successfully done」を検索します。
grep -B 20 'process successfully done' rsync_<上で確認した日時を示す文字列>.log
- ファイルの末尾が表示されたら、コピーが全て無事に完了しています。
- 何も表示されない場合は、一部のコピーが失敗したか、コピー完了前にプロセスが中断されています。
- 以下のコマンドを実行し、標準エラー出力のログファイルの内容を確認します。
cat rsync_error_<上で確認した日時を示す文字列>.log
- 末尾に「./rsync_with_progress.sh process failed.」と表示されていれば、一部のコピーが失敗しています。エラー文や標準出力のログファイルの内容を読んで対処し、その後「②-iii. (中断した場合)コピーの再開手順」の項を参照して再度コピーを実施してください。
- 末尾に「./rsync_with_progress.sh process failed.」と表示されていなければ、コピー完了前にプロセスが中断されています。「②-iii. (中断した場合)コピーの再開手順」の項を参照してコピーを再開してください。
標準出力のログファイル末尾は、以下のように表示されます。(例えば、4行目と6行目から、コピーされたファイル数と総ファイルサイズがわかります。)
Number of files: 45,125 (reg: 36,031, dir: 9,094) <-- コピー元のファイル&フォルダの総数
Number of created files: 45,124 (reg: 36,031, dir: 9,093) <-- コピー先で生成されたファイル&フォルダの総数
Number of deleted files: 0 <-- コピー先で削除されたファイル&フォルダの総数
Number of regular files transferred: 36,031 <--- コピーされたファイル数
Total file size: 219.90G bytes <-- コピー元の総ファイルサイズ
Total transferred file size: 219.90G bytes <-- コピーされた総ファイルサイズ
Literal data: 219.90G bytes <-- 実際に送信されたデータサイズ
Matched data: 0 bytes <-- コピー先と一致してスキップされたデータサイズ
File list size: 704.47K <-- コピーファイル一覧情報のデータサイズ(bytes)
File list generation time: 5.208 seconds <-- コピーファイル一覧情報の作成にかかった時間
File list transfer time: 0.000 seconds <-- コピーファイル一覧情報の転送にかかった時間
Total bytes sent: 219.96G <- コピー元からコピー先に送信したデータの総サイズ(bytes)
Total bytes received: 711.98K <- コピー先からコピー元に送信したデータの総サイズ(bytes)
sent 219.96G bytes received 711.98K bytes 4.61M bytes/sec <-- データの平均転送速度
total size is 219.90G speedup is 1.00 <-- 転送効率(コピー対象の総ファイルサイズ/実際にコピーされた総ファイルサイズ)
2025-04-05 10:28:52 [INFO] ./rsync_with_progress.sh process successfully done!!
④漏れなく破損なくコピーされたことの確認
前節まででコピーが完了したと思われるので、-c
オプションを用いて、破損なく完全コピーされたかどうかを確認します。
- 「①フォルダのコピーを開始」の節の手順を再度実施します。
ただし、メインで実行するスクリプトに、以下のように-c
オプションを末尾に追加することで、コピー元とコピー先とで、「チェックサム」が異なるファイルが存在しないか確認します。
nohup \
./rsync_with_progress.sh "$COPY_SOURCE_PATH" "$COPY_DESTINATION_PATH" '-c' \
> ./rsync_$(date +%Y%m%dT%H%M%S).log \
2> ./rsync_error_$(date +%Y%m%dT%H%M%S).log \
&
- 「③フォルダのコピーの完了確認」の節を参考に、コピーされたファイル数を確認します。
- コピーされたファイル数が0件の場合、全てのファイルがチェックサムレベルで同一で、1度目のコピー完了の時点で破損なくコピーされていたことを確認できます。
- コピーされたファイル数が1件以上ある場合、1度目のコピーの際に破損してコピーされたファイルが存在していたことがわかります。その場合、今回の実行により改めてコピーされたはずですが、そのコピーが破損ないかどうか念のため再確認するのであれば、本節の手順を再実施します。
- 自動スリープや自動シャットダウンの設定を停止していた場合は、すべて完了したあとに設定を元に戻しておきます。

手順は以上です。
ここまで読んでいただき、ありがとうございました!
[補足1] 使用しているrsyncのオプション
※下記の説明の多くについて、こちらのWebサイト2より引用しています。
オプション | 説明 |
---|---|
-a | アーカイブモード(「-rlptgoD --no-H --no-A --no-X 」に相当。それぞれのオプションは以下。) |
(-r ) | フォルダを再帰的に処理する |
(-l ) | シンボリックリンクをシンボリックリンクのままコピーする |
(-p ) | パーミッションを保持する |
(-t ) | タイムスタンプを保持する |
(-g ) | 所有グループをそのまま保持する |
(-o ) | 所有者をそのまま保持する(自分以外の所有者を保持するにはroot権限が必要) |
(-D ) | デバイスファイルや特殊ファイルを保持する |
(--no-H ) | ハードリンクを保持しない |
(--no-A ) | ACL(アクセス制御リスト)を保持しない |
(--no-X ) | 拡張属性を保持しない |
-v | 動作内容を表示する |
-h | 数字を読みやすい単位で表示する |
--stats | ファイル数や転送サイズを表示する |
--info=progress2 | [>=3.1.0] (処理全体に対して)コピーの進行状況を表示する3 |
--no-inc-recursive | [>=3.1.0] recursive algorithmをオフにすることで、コピー開始前にフォルダ構造を全て解析するようにする[3] |
--progress | (1ファイルごとに)コピーの進行状況を表示する |
-e | リモートシェルを指定する(デフォルト値:rsh [<2.6.0] / ssh [>=2.6.0])4。リモートシェルのポート番号を指定する場合や、公開鍵認証を用いる場合など、オプションを指定する必要がある場合は、リモートシェルのコマンドを含めた文字列として渡す(例:-e 'ssh -p 2345' )5。 |
-c | 更新日とサイズではなく、チェックサムで変更の有無をチェックする |
--rsync-path | リモートサーバ間でコピーする場合、リモートサーバ上のrsyncコマンドのパスを指定する |
--dry-run | 試験モード。実際には動作せず、動作内容だけ表示する |
-u | コピー先のファイルの方が新しい場合はコピーせずにスキップする |
-m | 空のフォルダはコピー対象にしない |
[補足2] rsyncのアップデート手順
OSにより手順が異なります。
Macの場合
- 「ターミナル」アプリを立ち上げます。
- (コピー時にファイルの所有者やアクセス権限を保持したい場合※)以下のコマンドを実行し、管理者権限ユーザ(root)にログインします。元の一般権限ユーザのログインパスワードを求められたら、入力します。※「⓪事前準備」の項の2点目を参照。
sudo su -
- 以下のコマンドを実行し、現時点の実行対象のrsyncのバージョンを確認しておきます。
rsync --version
- 以下のコマンドを実行し、現時点の実行対象のrsyncがどこにあるかを確認しておきます。
which rsync
- 以下のコマンドを実行し、Macのパッケージ管理ツール「Homebrew」がインストールされていることを確認します。バージョンが表示されずにエラーとなる場合は、インストールされていません。
brew --version
- (Homebrewがインストールされていない場合)以下のコマンドを実行し、Homebrewをインストールします。(コマンドは脚注6の公式HPから引用。)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- (Homebrewがインストールされている場合)以下のコマンドを実行し、Homebrewのバージョンを最新化します。
brew update
- 以下のコマンドを実行し、Homebrewでrsyncがインストールされているかどうかを確認します。何も表示されなければ、Homebrewではインストールされていません。
brew list | grep rsync
- (Homebrewでrsyncがインストールされていない場合)以下のコマンドを実行し、Homebrewでrsyncをインストールします。
brew install rsync
- (Homebrewでrsyncがインストールされている場合)以下のコマンドを実行し、Homebrewのrsyncをアップデートします。
brew upgrade rsync
- 以下のコマンドを実行し、現時点の実行対象のrsyncがどこにあるかを確認します。
which rsync
/usr/local/bin/rsync
と表示: Homebrewでインストールしたrsyncが実行対象になっているため問題ありません。以下のコマンドを実行して、rsyncのバージョンが最新化されていることを確認し、rsyncのアップデートは完了です(以降の手順を実施する必要はありません)。rsync --version
/<それ以外の場所>/rsync
と表示(冒頭で確認した場所から変わっていない): 元々インストールされていたrsyncが引き続き実行対象になっています。以降の手順を実施して、Homebrewでインストールしたrsyncを実行対象にします。
- 以下の4つのコマンドを実行し、Homebrewでインストールしたrsyncが優先して実行されるように、実行ユーザの環境変数
PATH
を永続的に変更します。echo 'export PATH=/usr/local/bin:$PATH' >> ~/.profile
source ~/.profile
if [ -f ~/.bash_profile ];then sed -i '1isource ~/.profile' ~/.bash_profile;fi
if [ -f ~/.zprofile ];then sed -i '1isource ~/.profile' ~/.zprofile;fi
- 以下のコマンドを実行し、
/usr/local/bin/rsync
と表示されることで、Homebrewでインストールしたrsyncが実行対象になったことを確認します。which rsync
- 以下のコマンドを実行し、Homebrewでインストールしたrsyncのバージョンが最新化されていることを確認します。
rsync --version
Ubuntu/Debian系OSの場合
- sudoコマンドで管理者権限を持つことができるユーザ(※)でシェルにログインします(※/etc/sudoersに記載されているユーザ)。
- 以下のコマンドを実行し、パッケージ管理ツール「APT」により更新可能な最新パッケージを全取得してきます。パスワードが求められたら、実行ユーザのログインパスワードを入力します。
sudo apt update
- 以下のコマンドを実行し、APTでrsyncを最新バージョンにアップデートします。インストールされていない場合は、インストールします。
sudo apt install rsync
- APTによりrsyncが最新化されたことを確認します。
rsync --version
CentOS/RHEL系OS・Fedoraの場合
- sudoコマンドで管理者権限を持つことができるユーザ(※)でシェルにログインします(※/etc/sudoersに記載されているユーザ)。
- 以下のコマンドを実行し、パッケージ管理ツール「Dandified Yum」により更新可能な最新パッケージを全取得してきます。パスワードが求められたら、実行ユーザのログインパスワードを入力します。
sudo dnf check-update
- 古いOSでは「dnfというコマンドがない」というエラーになるので、その場合は以下のように前身の「Yum」を使用します。
sudo yum check-update
- 古いOSでは「dnfというコマンドがない」というエラーになるので、その場合は以下のように前身の「Yum」を使用します。
- 以下のコマンドを実行し、Dandified Yumでrsyncを最新バージョンにアップデートします。インストールされていない場合は、インストールします。
sudo dnf install rsync
- Dandified Yumが存在しない場合は以下を実行します。
sudo yum install rsync
- Dandified Yumが存在しない場合は以下を実行します。
- Dandified Yumによりrsyncが最新化されたことを確認します。
rsync --version
[補足3] 表示されている進捗%から残りのコピー時間を推定できるか
rsync(バージョン3.1.0以上)にオプション-v
-h
--info=progress2
--no-inc-recursive
を指定したときの進捗状況のログ出力は以下のようになります7。
34.46G【イ】 15%【ロ】 2.44MB/s【ハ】 3:44:31【ニ】 (xfr#16104【ホ】, to-chk=25177【ヘ】/45125【ト】)
(イ)コピー済みのデータサイズ(バイト)
(ロ)コピー予定のデータサイズのうち転送済みのデータサイズの進捗%
(ハ)現在のデータ転送速度(バイト毎秒)
(ニ)現在までのコピー所用時間(hh:mm:ss)
(ホ)現在処理中のファイルが何個目か
(ヘ)処理対象のファイルおよびフォルダが、あと何個残っているか
(ト)処理対象のファイルおよびフォルダの全個数
よって、データ転送速度(ハ)が一定でさえあれば、現在までの所用時間(ニ)と進捗%(ロ)の情報を用いて、以下のように残りの所用時間を計算できるはずです。<残りの所用時間> = <現在までの所用時間(ニ)> × ( 100% ÷ <進捗%(ロ)> - 1 )
・・・式(*)
上記の15%時点の例の場合は、3:44:31 × ( 100% ÷ 15% - 1) = 21:12:10
となり、あと21時間強かかると推定されます。しかし、実際にコピー全体にかかった時間は13時間16分でしたので、ここまでの3:44:31を差し引くと、実際よりも2倍以上の残り時間が推定されてしまっています。
原因としては、データ転送速度(ハ)の変動が考えられます。以下の図をご覧ください。


コピー全体に実際にかかった時間から逆算した場合の、表示されて欲しい理想的な進捗%推移(図中の橙色点線)と比較すると、実際に表示されていた進捗%推移(図中の藍色実線)は常に下回っています。これにより、3:44:31経過時点で残り時間を推定したとしても、実際よりも遙かに長い時間となってしまうことがわかります。
ここで、データ転送速度(灰色実線)に注目すると、3:44:31時点では2,499kB/sですが、最終的には4,495kB/sまで上昇しています。よって、先述の式(*)の前提となる「データ転送速度が一定」という条件が正しくなかったことが原因で、残り時間の推定が上手くいっていないことがわかります。
なぜ今回のコピーで、データ転送速度が徐々に上昇しているのかは正確にはわかりませんが、恐らくコピー元のPCとコピー先のサーバのCPUなどの空き状況に起因すると思っています。特に最初の3~4時間はPC上で別の作業をしていましたので、その作業にリソースを取られてコピーが捗らなかったのだと思います。
したがって、ログ出力の内容から式(*)を用いることで、残りのコピー時間を推定できますが、飽くまで「その時点までの平均データ転送速度が維持された場合」という仮定の下であることに注意が必要です。その時点以降にデータ転送速度が上昇するか下降するかは、なかなか予測できないかと思いますが、その可能性を考慮しておきましょう。
脚注
- 本手順の動作確認環境
[全体手順確認]
・Mac OS 10.13.6
・Bash 3.2.57(1)-release
・Homebrew 4.4.24
・rsync 3.4.1
[SSH・Ubuntu手順確認]
・Ubuntu 22.04.3 LTS (on Windows11 WSL)
・Bash 5.1.16(1)-release
・APT 2.4.11 (amd64)
・rsync 3.2.7 ↩︎ - “rsyncコマンド(その1)――ファイルやディレクトリを同期する:Linux基本コマンドTips(82) – @IT”, https://atmarkit.itmedia.co.jp/ait/articles/1702/02/news031.html. ↩︎
- “[Linux] rsyncで進捗を確認する”, https://to-31.blogspot.com/2018/04/linux-rsync.html. ↩︎
- “rsync 2.6.0 以降は -e ssh がデフォルトです | キュア子の開発ブログ”, https://curecode.jp/tech/rsync-default-remote-shell-is-ssh/. ↩︎
- “rsyncで公開鍵を指定してデータ転送する方法 – yoshiyoshi-1413’s blog”, https://yoshiyoshi-1413.hatenablog.com/entry/2018/03/12/162848. ↩︎
- “macOS(またはLinux)用パッケージマネージャー — Homebrew”, https://brew.sh/ja/. ↩︎
- “Understanding the output of –info=progress2 from rsync – Unix & Linux Stack Exchange”, https://unix.stackexchange.com/questions/215271/understanding-the-output-of-info-progress2-from-rsync. ↩︎