#!/bin/bash # this file is meant to be sourced, not executed directly # if destination argument is not provided, fail if [[ $# -lt 1 ]]; then echo "$(basename $BASH_SOURCE): error: no destination provided!" >&2 return 1 elif [[ $# -gt 1 ]]; then echo "$(basename $BASH_SOURCE): error: too many arguments!" >&2 return 1 fi # provide sshp command for executing commands on remote computer sshp() { echo "$@" >&$_sshp_in echo "echo EOF" >&$_sshp_in sed '/EOF/Q' <$_sshp_out } # assign dest to variable _sshp_dest=$1 # create temporary directory _sshp_tmpdir=$(mktemp -d) mkfifo $tempdir/in $tempdir/out _sshp_out=$_sshp_tmpdir/out # assign input to a file descriptor so it doesn't get closed exec {_sshp_in}<>$tempdir/in # trap exit to do cleanup trap "{ exec {_sshp_in}>&-; ssh -O exit -S $_sshp_tmpdir/ssh $_sshp_dest &>/dev/null; rm -rf $tempdir; }" EXIT # login with master so ssh can ask password if necessary ssh -M -Nf -S $tempdir/ssh $_sshp_dest # login with redirection for the persistent connection ssh -S $tempdir/ssh medusa 0<&$_sshp_in 1>$_sshp_out 2>$_sshp_out & # clear output sshp true &> /dev/null # ask for password and run sudo so password can be cached (printf "[sudo] password for $(remote echo \$USER)@$(remote hostname): " read -s password printf '\n' echo "sudo -S true" >&3 echo $password >&3) # clear output sshp true &> /dev/null