#!/bin/bash toolName="ssh" toolIdentity=~/.ssh/id_rsa aList="" aHost="" # default ssh port aPort="22" step_1_info() { echo "Install $toolName"; } step_1_alias() { ALIAS="install"; } step_1() { exe apt update exe apt install ssh } step_3_info() { echo "Create $toolName authentication keys"; } step_3_alias() { ALIAS="create"; } step_3() { exep "ssh-keygen -l -f $toolIdentity 2>>/dev/null" if [ $? -eq 0 ]; then echo " [I] Using key found at $toolIdentity." return 0 fi exe ssh-keygen -b 4096 -t rsa -C "$(hostname)" -N "" -f $(realpath $toolIdentity) } step_5_info() { shift local arg local sshOption="[OPTIONS] " local userHost="" local userPort=" [PORT]" for arg in "$@" ; do case "$1" in -4) sshOption="-o Addressfamily=inet " shift ;; *) break ;; esac done if [ ! -z $1 ] ; then userHost="$1"; userPort=":22"; fi if [ ! -z $2 ] ; then userPort=":$2"; fi echo "Send key to remote host ${sshOption}${userHost}$userPort" echoinfo "[OPTIONS]" echoinfo " -4 : Force Ipv4" } step_5_alias() { ALIAS="sendkey"; } step_5() { shift local arg local sshOption local sshHost local sshPort=22 for arg in "$@" ; do case "$1" in -4) sshOption="-o Addressfamily=inet" shift ;; *) break ;; esac done if [ -z "$1" ] || [ "$1" == "" ] ; then echoerr " [E] Host not provided." return 1 else sshHost="$1" fi exep "ssh-keygen -l -f $toolIdentity 2>>/dev/null" saveReturn $? endReturn -f "Key $(realpath $toolIdentity) not found.\n Create one first." if [ ! -z "$2" ] && [ "$2" != "" ] ; then sshPort=$2 fi exe ssh-copy-id -p ${sshPort} ${sshOption} ${sshHost} } step_10_info() { echo "Send command(ssh)/file(scp) list to remote(s) [USER:HOST]"; } step_10_alias() { ALIAS="sendlist"; } step_10() { aList=$2 aHost=$3 # Set port only if not empty if [ ! -z "$4" ] || [ "$4" != "" ]; then aPort=$4 fi parseList $aList saveReturn $? endReturn -f "Parsing error" } # parseList [CMDFILE] # Parse a list to transfer files and/or execute commands on one or different hosts # # List format # ||[STRING2]|[OPTIONS] # COMMAND h|H|host - Change user@host:port for the following ssh/scp commands # f|F|file - Source- and destination file path combination # c|C|command - Execute command on the remote host # # STRING h - user@host # f - source file path # c - shell command string # # STRING2 h - port # f - destination file path # c - not used # # OPTIONS h - not used # f - Options passed to scp # c - not used # parseList() { local errorMsg="" if [ -z "$1" ] || [ ! -f "$1" ]; then if [ -z "$1" ] || [ "$1" == "" ] ; then echoerr " [E] No Command list found" else echoerr " [E] Command list not found: $1" fi if [ ! -z "$1" ] && [ $DRY == 0 ] && [ $QUIET == 0 ] ; then read -p " Create template there y/[n]? " answer case "$answer" in y|Y) addConf -s "$listFileTemplate" "$1" ;; *) ;; esac fi return 1 fi echo " [I] Parsing $(realpath $1) ..." local line=1 # Working loop without ssh "stealing standard input" by # https://unix.stackexchange.com/questions/24260/reading-lines-from-a-file-with-bash-for-vs-while while IFS='|' read -r lcmd lsrc ldst lopt<&3; do case "$lcmd" in h|H|host) if [ -z "$lsrc" ] || [ "$lsrc" == "" ]; then errorMsg="No host found" #Prevent unwanted actions if parsing is continued aHost="" saveReturn 1 else aHost="$lsrc" if [ ! -z "$ldst" ] || [ "$ldst" != "" ]; then aPort=$ldst else # Set port (back) to default in case no port is given # after previous change aPort=22 fi echo Target host: ${aHost}:$aPort fi ;; f|F|file) if [ -z "$aHost" ] || [ "$aHost" == "" ]; then errorMsg="No host found" saveReturn 1 else exe scp $lopt -P $aPort $lsrc ${aHost}:$ldst saveReturn $? errorMsg="scp to $aHost failed with $?" fi ;; c|C|command) if [ -z "$aHost" ] || [ "$aHost" == "" ]; then errorMsg="No host found" saveReturn 1 else exe ssh -p $aPort $aHost $lsrc saveReturn $? errorMsg="ssh to $aHost failed with $?" fi ;; *) # Making comments possible ((line++)) continue ;; esac getReturn if [ $? -ne 0 ] ; then echoerr -e " [E] $line:$errorMsg" if [ $QUIET -eq 0 ] ; then endReturn -f "Stop on first error" fi fi ((line++)) done 3<"$1" echo " [I] Parsed $((--line)) lines" } listFileTemplate="# following files are send to host given on command line f|/sourcedir/sourcefile|/destdir/destfile f|/sourcedir/sourcefile|/destdir/destfile # host and port are changed for the following lines h|user@host2|port2 f|/sourcedir/sourcefile|/destdir/destfile # copy source recursively f|/sourcedir/sourcefile/dir|/destdir/destfile|-r c|/destdir/updatescript.sh # host is changed and port set to default 22 for the following lines h|user@host f|/sourcedir/sourcefile|/destdir/destfile f|/sourcedir/sourcefile|/destdir/destfile c|/destdir2/update.sh" VERSION_SEQREV=10 . sequencer.sh