#!/bin/bash toolName="ssh" toolIdentity=~/".ssh/id_rsa" aList="" aHost="" # default ssh port aPort="22" step_1_info() { echo "Install $toolName"; } step_1_alias() { echo "install"; } step_1() { exe apt update exe apt install ssh } step_3_info() { echo "Create $toolName authentication keys"; } step_3_alias() { echo "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() { echoinfoArgs "[OPTIONS] [PORT]" echo "Send key to remote host" echoinfo "[OPTIONS]" echoinfo " -4 : Force Ipv4" } step_5_alias() { echo "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 error -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() { echoinfoArgs " [USER:HOST] [PORT]" echo "Send command(ssh)/file(scp) list to remote(s)" echoinfo "[USER:HOST] and [PORT] are overwritten by \"host\" command from " } step_10_alias() { echo "sendlist"; } step_10() { shift aList=${1:-} aHost=${2:-} # Set port only if not empty if [ -n "${3:-}" ]; then aPort=$3 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:-}" ]; then error -e "No Command list found" else error -e "Command list not found: $1" fi if [ -n "${1:-}" ] && dry || interactive ; then read -p " Create template there y/[n]? " answer case "$answer" in y|Y) addConf -s "$listFileTemplate" "$1" ;; *) ;; esac fi return 1 fi info "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" ]; then errorMsg="No host found" #Prevent unwanted actions if parsing is continued aHost="" saveReturn 1 else aHost="$lsrc" if [ ! -z "$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" ]; 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" ]; 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 error -e -e " [E] $line:$errorMsg" if interactive ; then endReturn -f "Stop on first error" fi fi ((line++)) done 3<"$1" info "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" readonly sqr_minVersion=16 . sequencer.sh