shell-network/modules/ssh-copy.func

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
}