1

I have a bash script which loops over a server list, runs a couple of remote commands via SSH, and writes the output of those commands to a local file. For every command I run on the remote server I open a new SSH session. Is there a way that only one SSH session remains open to a server, and that I can run multiple commands which the output I can redirect to a local file?

5 Answers 5

2

You want to look into the ControlMaster setting for SSH. That allows you to create a single SSH connection and then have all the other SSH connections to the same server multiplex over that one connection. Very handy.

3
  • Would this not add a lot of complexity in your script to start the master and kill it again after. Oct 27, 2009 at 11:10
  • TANSTAAFL. Virtual memory adds a lot of complexity to your OS kernel, but we do it anyway because the benefits outweigh the disadvantages.
    – womble
    Oct 27, 2009 at 12:15
  • No there's not a significant increase in complexity because ControlMaster can be made automatic, and then ssh handles creating and removing the master (unix-domain) socket. Oct 29, 2009 at 21:51
1

Note: When you say local file, I am not sure if you mean local the machine you just ssh'd into, or if you mean local to the machine the starts the ssh session.

Push vs Pull:
It sounds like this might not be the right tool, maybe you just want to use cron on each local machine? If information is needed from the master, you can have the cron job fetch a file from the server. This would be more of a pull method, the ssh is what I would call push method. I can't say which is better for your situation, but this may be something to think about.

Run Multiple Commands:
I don't understand if you mean keep the session open for each itteration of the multiple commands, or just have it sort of always open. If it is the former, you can just use semi-colons between commands, or && to make so the next command will only be executed if the first works. For example:

#bar echoed only if foo exists and can be read
ssh myServer 'cat foo && echo bar'
ssh myServer 'cat foo; echo bar'

You can also do stuff like the following if you want to specify use of things in a shell:

ssh myServer "bash -c 'cat foo && echo bar'"

Lastly, you could always just put the script on each server, and just run that.

1

The "expect" tool could also do what you want, but involves writing tcl.

1

To expand on the ControlMaster use, here's a slightly more concrete example:

CONTROL=/tmp/ssh-control-`date +%s`-$RANDOM
ssh -o BatchMode=yes -NfM -S $CONTROL &
MASTERPID=$?

ssh -o BatchMode=yes -S $CONTROL user@host command1 > outfile1
ssh -o BatchMode=yes -S $CONTROL user@host command2 > outfile2

kill $MASTERPID

This is largely untested, but it should give you the right general idea.

0

You can run several commmands in sequence by starting a shell on the remote system and passing it the commands:

ssh server "echo this is; all in one session"

will automatically pass the quoted string through a remote shell. Beware of shell quoting rules, though!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .