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.

4 Responses to “How to resume a broken scp transfer”

  1. rsync –inplace ?

  2. Indeed, that does the trick! Thanks!

  3. Indeed, invoking rsync via SSH will resume any file transfer.

  4. rsync’s rolling checksums will mean a lot of overhead and perform rather poorly for large files (e.g. 100 GB). Curl would simply append the data which is much more efficient if you can assume that the file has not been changed in the meantime.

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2012 Eugeni's blog Suffusion theme by Sayontan Sinha