#!/bin/bash # indirect-scp(1) v1.0, an scp(1) wrapper that tries to do an indirect # copy if a direct copy between two hosts fails. # # Copyright, Walter Doekes (C) 2012. License: Public Domain # # Imagine a scenario where your Desktop has access to ServerA and # ServerB, but they don't have access to each other. Using regular scp # on Desktop to copy stuff from ServerA to ServerB will then fail. This # script adds an indirect copy fallback, copying the data via Desktop. # # Installation: # cd /usr/local/bin # wget http://wjd.nu/files/2012/02/indirect-scp.sh -O indirect-scp # chmod 755 indirect-scp # ln -s indirect-scp scp # # Step 1: try regular scp. Skip this step if the wrapper isn't called # as scp. [ "`basename "$0"`" = scp ] && /usr/bin/scp "$@" ret=$? # Did it go well? Exit. [ $ret -eq 0 ] && exit 0 # Guess whether this was a copy between two machines. It should have at # least two colons (':') in the argument list. One for the source and # one for the destination host. colons=`echo "$@" | sed -e 's/[^:]//g'` if [ ${#colons} -le 1 ]; then # One or zero colons. exit $ret fi # Step 2: try again, but use a local copy. The $@-stuff below is bash # specific. echo "(falling back to indirect copy...)" >&2 dir="`mktemp -d`" || exit 1 # and mktemp -d isn't supported everywhere n_args=$# n_args_minus_one=$((n_args - 1)) # Copy sources to local... /usr/bin/scp "${@:1:$n_args_minus_one}" "$dir"/ ret=$? # Copy local to destination... if [ $ret -eq 0 ]; then echo "(copy from here to destination...)" >&2 /usr/bin/scp -p -r "$dir"/* "${@:$n_args:1}" ret=$? fi # Remove temp dir. First run shred over the files to make recovery # harder. echo "(cleaning up temporary files...)" >&2 [ -x `which shred` ] && find "$dir" -type f -print0 | xargs -0 shred rm -rf "$dir" # Return status. exit $ret