Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
add comment

5 Answers

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.

share|improve this answer
    
Would this not add a lot of complexity in your script to start the master and kill it again after. –  David Pashley Oct 27 '09 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 '09 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. –  Jim Zajkowski Oct 29 '09 at 21:51
add comment

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.

share|improve this answer
add comment

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!

share|improve this answer
add comment

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

share|improve this answer
add comment

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 command1 > outfile1
ssh -o BatchMode=yes -S $CONTROL command2 > outfile2

kill $MASTERPID

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

share|improve this answer
add comment

Your Answer

 
discard

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.