Setup and use SSH ControlMaster Session in a Shell

2019-02-19 12:06发布

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?

标签: shell ssh
1条回答
Bombasti
2楼-- · 2019-02-19 12:55

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.

查看更多
登录 后发表回答