Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I think that the code that I already have is not very efficient as it has to connect each time to the same machine and execute a command. Code:

tmp=$(ssh -nq $USER@$IP "$COMMAND" 2>> $LOG)
tmp1=$(ssh -nq $USER@$IP "$COMMAND1" 2>> $LOG)
tmp2=$(ssh -nq $USER@$IP "$COMMAND2" 2>> $LOG)
tmp3=$(ssh -nq $USER@$IP "$COMMAND3" 2>> $LOG)

Where $COMMAND in most of the cases is some kind of grep.

Can I somehow store the ssh connection or refactor the code so it won't connect each time to the machine ?

share|improve this question
Your last command overwrites tmp2. Should it be tmp3? – ott-- Feb 1 '13 at 10:16
tmp=$(ssh -nq $USER@$IP "$COMMAND ; $COMMAND1 ; ..." 2>> $LOG) – ott-- Feb 1 '13 at 10:18
@ott-- yes, that was just a typo; Will this append result of the command to the variable or will it overwrite it ? – Patryk Feb 1 '13 at 10:20

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)" \
    tmp3 "$(command3)"')"

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~/.bashrc).

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 $tmp.

share|improve this answer

You can use a Here Document:

cat <<EOF | ssh $USER@$IP 2>>$LOG
grep x *
grep -i y *.log
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.