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?
OpenSSH has an option called ControlMaster that enables the sharing of multiple sessions over a single network connection. This means that you can connect to the cluster once, enter your password and verification code, and have all other subsequent ssh sessions (including svn , rsync , etc.
Bash script SSH is a common tool for Linux users. It is needed when you want to run a command from a local server or a Linux workstation. SSH is also used to access local Bash scripts from a local or remote server.
controlpath /tmp/ssh-%r@%h:%p : Specify the path to the control socket used for connection sharing. In the path, %h will be substituted by the target host name, %p the port, and %r by the remote login username.
Your code looks fine. I haven't tested it, but the first process that tries to use the master connection should probably block until the master connection has actually successfully been established. You can use the -N
option to avoid running a spurious shell on the master connection:
ssh -N -o 'ControlMaster=yes' -S "$ssh_control_socket" "$HOST" &
It's perfectly fine to simply kill the ssh
process once all the subordinate sessions have completed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With