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

I need to loop through and ssh to multiple hosts and run a series of commands on each.

something like:

for i in $(jot -w '%02.0f' 14 1)
>do ssh user@host$i sudo -i "command1; command2; command3"
>done

but I can't get it to work correctly. I've seen various things on The Google like sudo sh -c, piping to sudo, etc, but can't figure it out.

  • I'm ssh'ing as a regular user that can sudo with no password (ssh as root not enabled)
  • command1 not returning 0 should not prevent command2 from running, etc, hence ;
  • I'm running the loop from a mac, hence jot -w, which is roughly equivalent to seq -f in linux
  • ssh'ing to CentOS 5.4
  • I'd like it to run with root's $PATH so I don't have to specify the full path to the commands, but it's not totally necessary

thanks in advance!

share|improve this question
1  
Bash alternatives to either 'jot' or seq: printf '%02d ' {1..14} or in Bash 4: for i in {01..14} (Bash < 4 ignores the leading zero). –  Dennis Williamson Nov 17 '10 at 22:42

5 Answers 5

up vote 5 down vote accepted

I find that getting the quoting correct is pretty annoying. Instead I tend to just pass commands to bash on the remote host through a pipe instead. This way you don't have to worry about getting the escaping right in your ssh command line. Just pass into the pipe exactly what you would type if you were connected interactively.

CMDS="sudo bash -c '/usr/bin/id; /usr/bin/id; '/usr/bin/id"
for i in 0 1; do
  echo $CMDS | ssh -t host$i bash
done

Which returns

uid=0(root) gid=0(root) groups=0(root)
uid=0(root) gid=0(root) groups=0(root)
uid=0(root) gid=0(root) groups=0(root)
share|improve this answer

Trying to pass quoted command strings over ssh is always a challenge. You don't mention what sort of error messages you're getting, but here are a few thoughts:

The default sudo configuration on many systems requires that your session have a valid TTY associated with it. This requires either (a) calling ssh with the "-t" option, or (b) remove the "requiretty" option from your sudo configuration.

This works for me (the destination is a set of RHEL5 systems):

for i in 0 1; do
  ssh -t host$i sudo -i "echo one; echo two; echo 'three four'"
done

This results in:

one
two
three four
Connection to host0 closed.
one
two
three four
Connection to host1 closed.

There are a variety of tools that will make your life easier if you do this sort of thing often:

And so forth. I usually just use shell scripts, myself.

share|improve this answer
1  
Are you sure you have your command escaped right? When I run ssh -t host sudo -i "/usr/bin/id; /usr/bin/id" the results I get suggest that the second command is not privileged. –  Zoredache Nov 17 '10 at 22:12
    
Zoredache is right, you need another layer of quotes/escapes or ssh will run sudo -i echo one and echo two etc as separate commands. Try: ssh -t host$i "sudo -i 'id; echo \" three four\"; id'" (that's three layers of quotes -- escaped double quotes [the arg to the echo command] inside single quotes [the command passed to sudo] inside double quotes [the command passed to ssh]). This can get arbitrarily confusing... –  Gordon Davisson Nov 17 '10 at 22:34

I think pssh is what you need to work with.

share|improve this answer

http://sourceforge.net/projects/clusterssh/

This is a clear winner :D

share|improve this answer

Have a look at BatchLogin:

http://batchlogin.sourceforge.net/

BatchLogin is a free software (GPL) licensed tool that allows you to manage connections to servers in serial format across diverse environments. It has its limitations, but for the most part, any script or data file can be automatically transferred and executed across a multiple server environment, regardless of the complexity of the "zone" (I.E.: iDMZ, DMZ, etc). It does this in a way that shell scripts and access to servers can easily be managed on a "per admin" basis.

share|improve this answer

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.