SCPが途中で切れるときの対処法

sh_dispatch_run_fatal: Connection to XXX.XXX.XXX.XX port 22: message authentication code incorrect

みたいなのが出て途中でscpが切れてしまうということが起きたが無事解決できたのでメモする。

 

解決法: -o ServerAliveInterval=1をオプションでつける。

例) scp -o ServerAliveInterval=1 サーバー クライアント

1秒ごとにシグナルを送り、サーバー側がidle状態と判断するのを防いでくれる。このオプションはsshでも使えるので、sshで似たようなことが起こっても解決できるかも。

常にこのオプションをつけたい場合は、bashrcに

alias scp='scp -o ServerAliveInterval=1'

と書くと良い。

 

それでもだめな時、

rsync --partial -r --progress --rsh=ssh サーバー クライアント

で何度もトライするって方法もあるらしい(切れた所からやり直せる)。

ただ同期したい場合は、

rsync --progress -r --append-verify  サーバー クライアント

で良い(この場合、途中のファイルはおそらく最初から転送し直し)。

 

終わった後に、

サーバー上のディレクトリ内(cd dir後)で

md5sum $(find . -type f) | tee ../dir.md5

を実行し、出来たdir.md5をクライアントのコピーしたディレクトリ手前に写し、

md5sum -c ../dir.md5

を実行すれば、ファイルが壊れていないかなどを確認できる。

(echo $? を実行し”0”が出力されればOK。)

 

最終手段(スクリプト 100回やり直す)

#!/bin/bash

retry() {
   MAX_RETRY=100
   n=0
   until [ $n -ge $MAX_RETRY ]
   do
      "$@" && break
      n=$[$n+1]
      sleep $[ ( $RANDOM % 15 )  + 1 ]s
   done
   if [ $n -ge $MAX_RETRY ]; then
     echo "failed: ${@}" >&2
     exit 1
   fi
}

retry rsync --partial --progress --rsh=ssh -r $server_name ./