How to resume a broken scp transfer
Well, this question appeared quite frequently to me. However, I never bothered with it, as I was either on a LAN, or had a different source from which I could resume using wget, or a file was sufficiently small to redownload it again. However, this time these approaches did not work:
- The file was big (a DVD ISO)
- The only way to access it was over a SSH connection
- The only authentication method it supported was public key authentication
- The directory from where the file was downloaded was read-only
- The link was sloooow
- I already had downloaded about 70% of the file
So I started looking for solutions. Most of ideas I found on google suggested using ‘rsync –partial –rsh=ssh‘, and indeed it could work. However, rsync tried to create a temporary file on the server, and, as the directory was read-only, it failed. There probably is some option to make it work, but I don’t have plenty of rsync experience. And this approach just looked to be over complicated.
After a bit of more googling, I found out that curl supported sftp backend. And, after a few minutes trying to figure out how to make it work with public key authentication, I finally figured it out:
curl -C - --pubkey ~/.ssh/key.pub --key ~/.ssh/key \
sftp://eugeni@somewhere/mnt/.../i586/my_precious_iso.iso \
-o my_precious_iso.iso
To shorten it up, it is possible to write a simple wrapper function (or a script) for bash:
#!/bin/bash
function scp_resume() {
URL="$1"
FILE="$2"
if [ "a$FILE" == "a" ]; then
echo "Usage: scp_resume <sftp url> <local target>"
return 1
fi
# the magic
curl -C - $URL -o $FILE
}
function scp_resume_key() {
URL="$1"
FILE="$2"
KEY="$3"
if [ "a$FILE" == "a" ]; then
echo "Usage: scp_resume <sftp url> <local target> <key file name>"
return 1
fi
# the magic
curl -C - --key $HOME/.ssh/$KEY --pubkey $HOME/.ssh/${KEY}.pub $URL -o $FILE
}
so it did the trick.










rsync –inplace ?
Indeed, that does the trick! Thanks!