143 lines
3.5 KiB
Bash
143 lines
3.5 KiB
Bash
#!/bin/bash
|
|
|
|
module_load ssh
|
|
module_load debug
|
|
|
|
sshcp () {
|
|
|
|
local SHOST; local DHOST; local dr; local sshargs; local args
|
|
local OPTS; local SOPTS; local SRC; local DEST;
|
|
local SPATH; local SPATH
|
|
|
|
help() {
|
|
|
|
cat <<EOF
|
|
usage:
|
|
sshcp <script options> src dest <scp options> -- <ssh options>
|
|
-d, destination host
|
|
-s, source host
|
|
-y, dry run. don't run the rscript just output the command that will be run
|
|
-h, this help text
|
|
EOF
|
|
|
|
}
|
|
|
|
# parse sshcp options
|
|
local OPTION
|
|
local OPTARG
|
|
local OPTIND
|
|
while getopts 'd:ys:h' OPTION; do
|
|
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
|
|
case "$OPTION" in
|
|
s)
|
|
# script filename to run
|
|
SHOST=$OPTARG
|
|
;;
|
|
y)
|
|
# dry run
|
|
dr=true
|
|
;;
|
|
d)
|
|
# run remote command as another user
|
|
DHOST=$OPTARG
|
|
;;
|
|
h)
|
|
help
|
|
return 0
|
|
;;
|
|
*)
|
|
>&2 echo fatal: unknown remote script option $OPTION, aborting
|
|
help
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
[[ ! $1 ]] && >&2 echo fatal: scp requires a source path to send && return 1
|
|
SRC=$1; shift
|
|
|
|
if [[ $SRC =~ ":" ]]; then
|
|
# echo source is remote
|
|
SHOST=${SHOST:-$(sed 's/\(.*\):.*/\1/' <<< "$SRC")}
|
|
SPATH=$(sed 's/.*:\(.*\)/\1/' <<< "$SRC")
|
|
else
|
|
# echo source is local
|
|
SPATH=$SRC
|
|
fi
|
|
|
|
DEST=$1;shift
|
|
if [[ $DEST =~ ":" ]]; then
|
|
destination is remote
|
|
DHOST=${DHOST:-$(sed 's/\(.*\):.*/\1/' <<< "$DEST")}
|
|
DPATH=$(sed 's/.*:\(.*\)/\1/' <<< "$DEST")
|
|
else
|
|
DPATH=$DEST
|
|
fi
|
|
[[ ! $DPATH ]] && >&2 echo fatal: scp requires a destination file path && return 1
|
|
|
|
if [[ ! $(get_user_host $DHOST) ]] && [[ ! $(get_user_host $SHOST ) ]]; then
|
|
>&2 echo fatal: need at least a valid remote source host $SHOST or remote destination host $DHOST, aborting remote copy
|
|
return 1
|
|
fi
|
|
|
|
[[ $DHOST && $SHOST && (! $DHOST = "$SHOST") ]] && { echo full remote copy must be same hosts; return 2; }
|
|
|
|
|
|
# parse ssh arguments from the rest
|
|
debug $( ( IFS=$','; echo all arguments: "$*" ) )
|
|
for ((d=1; d<$#; ++d)); do
|
|
[[ ${!d} == "--" ]] && break
|
|
done
|
|
|
|
if [[ $d -lt $# ]]; then # if there are extra ssh arguments
|
|
debug found -- at $d
|
|
sshargs=("${@:$d+1:$#}")
|
|
debug $( ( IFS=$','; echo "ssh arguments: ${sshargs[*]}" ) )
|
|
# [[ ! ${sshargs[0]} ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
|
|
args=("${@:1:$d-1}")
|
|
# reset script arguments to just those before --
|
|
# set -- "${args[@]}"
|
|
debug $( ( IFS=$','; echo remaining arguments to parse: "$*" ) )
|
|
fi
|
|
|
|
# # echo parse: $*
|
|
# if [[ ! $* =~ "--" ]]; then
|
|
# SOPTS=$*
|
|
# else
|
|
# SOPTS=$(sed 's/\(.*\)--.*/\1/' <<< "$*")
|
|
# OPTS=$(sed 's/.*--\(.*\)/\1/' <<< "$*")
|
|
# fi
|
|
|
|
# echo SOPTS $SOPTS
|
|
# echo OPTS $OPTS
|
|
|
|
module_load array
|
|
declare -a ret
|
|
# echo ssh -r "$SOPTS" "${DHOST:-$SHOST}"
|
|
# return
|
|
|
|
cmd="ssh -r ${sshargs[*]} ${DHOST:-$SHOST}"
|
|
String::split ret "$($cmd)" ,
|
|
local host=${ret[0]}; local sshopts=${ret[1]}; local sshpass=${ret[2]}
|
|
|
|
[[ -d $SPATH && ! $SHOST ]] && args+=(" -r")
|
|
|
|
# todo test remote to local copy
|
|
|
|
local cmd="$sshpass scp ${args[*]} $sshopts $([[ $SHOST ]] && echo "${host}:")$SPATH $([[ $DHOST ]] && echo "${host}:")$DPATH"
|
|
# echo $cmd
|
|
if $([[ $dr ]] && echo "echo ") $cmd; then
|
|
debug copy success
|
|
debug $(ssh ${sshargs[*]} ${DHOST:-$SHOST} ls -la $DPATH)
|
|
else
|
|
>&2 echo remote copy failed
|
|
>&2 echo $cmd
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
|