If the remote user's shell is ksh93, zsh or bash (or
sh implemented as any of those), you could do:
eval "$(ssh -nq "$user@$host" '
printf "%s=%q\n" \
tmp1 "$(command1)" \
tmp2 "$(command2)" \
However note that you'll be missing on the exit status of the remote commands. And that could potentially allow the remote user to cause you to execute arbitrary commands (for instance by outputting something in their
Another option is to use the
ControlMaster feature of
ssh to share a connection between several invocations of ssh. You could also use the
auto mode. Something like:
mkdir -p -- ~/.ssh/ctl
tmp1=$(ssh -o ControlMaster=auto \
-o ControlPath="$HOME/.ssh/ctl/%L-%r@%h:%p" \
-o ControlPersist=5m -nq "$user@$host" cmd1)
(and same for
tmp2...). That syntax re-uses an existing connection if it exists or creates a new one otherwise. It will be terminated after 5 minutes of being idle, or you can close it explicitly with:
ssh -o ControlPath="$HOME/.ssh/ctl/%L-%r@%h:%p" -O exit "$user@$host"
The first invocation will take time, because it will perform the connection and authentication, while the following ones will be a lot faster.
Of course, if you don't need the three command outputs to go in three different variables you can do:
tmp=$(ssh -nq "$user@$host" '
So the 3 command outputs will appear concatenated in