I'm writing a script which has several sets of commands that it needs to run on a remote server, with processing of results in between. Currently this is achieved by running ssh
for each set of commands, however this requires a new connection to be made and authenticated each time, which is slow.
I recently read about the ControlMaster
option in SSH, which seems like exactly what I need, namely the ability to run separate SSH sessions through a single SSH connection.
However, what I'm extremely unclear on is how exactly I would achieve this in my shell script. For example, I was thinking of constructing it like so:
#!/bin/sh
HOST="$1"
# Make sure we clean up after ourselves
on_complete() {
kill $ssh_control_master_id
rm -r "$tmp_dir"
}
trap 'on_complete 2> /dev/null' SIGINT SIGHUP SIGTERM EXIT
tmp_dir=$(mktemp -d "/tmp/$(basename "$0").XXXXXX")
ssh_control_socket="$tmp_dir/ssh_control_socket"
# Setup control master
ssh -o 'ControlMaster=yes' -S "$ssh_control_socket" "$HOST" &
ssh_control_master_id=$!
# Run initial commands
data=$(ssh -S "$ssh_control_socket" "$HOST" 'echo "Foo"')
# Process the data
echo "$data"
# Run some more commands
data=$(ssh -S "$ssh_control_socket" "$HOST" 'echo "Bar"')
# Process the second batch of data
echo "$data"
Just a simple example to give you an idea, but this doesn't seem to be the correct way to do this, as running it will either cause the second ssh
command to hang, or each command will just run normally (create their own connection). I'm also not sure how to go about waiting for the master connection to be established, i.e - I'm probably running my actual commands while the remote connection is still being established.
Also on a related note, what is the correct way to close the control master once it's running, is killing it and/or deleting its socket fine?