-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathindirect-scp
executable file
·69 lines (63 loc) · 2.11 KB
/
indirect-scp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/bin/bash
# indirect-scp (part of ossobv/vcutil) // wdoekes/2012 // Public Domain
#
# scp(1) wrapper that tries to do an indirect copy if a direct copy
# between two hosts fails.
#
# 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.
#
# NOTE: 2016-09-02: I just found out that scp(1) has the `-3` option to
# have the file copy go through localhost. That sort of defeats the
# purpose of this script. Although you'll miss out on the progress
# meter.
#
# 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
#
# Usage:
#
# scp user@serverA:/path/to/file user@serverB:/path/to/
#
# Step 1: try regular scp. Skip this step if the wrapper isn't called
# as scp (but as indirect-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 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 "$(command -v shred)" ] && find "$dir" -type f -print0 | xargs -0 shred
rm -rf "$dir"
# Return status
exit $ret