Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Wednesday, December 8, 2010

Running remote command over ssh with Groovy

This post is for those who are searching for how to run a remote command over ssh through a groovy script.  Hopefully it will save someone a lot of searching....spoiler alert:  There does not seem to be a clean way to do this.

It is trivial to run a command on a remote system over ssh, especially if you have keys set up between the machines that are communicating.  Just
ssh user@remote_server command_you_would_like_to_run'.

Things get surprisingly complicated when you want to script this kind of interaction.  I believe that this is because most ssh implementations use tty and it is made difficult by design to use in a scripted environment (and rightly so, since it is a security risk).

I simply wanted to connect to a remote server with groovy and list the files in a known directory.  I was hoping that I could do this with groovy's .execute().text since I did not need to send passwords or anything else because I have keys set up between the machines.  No dice.  I tried the array version of .execute too and still no joy.  What I ended up having to do is to create a simple bash script:

 #!/bin/bash
 ssh user@remote_server 'ls /directory_I_am_interested_in'


which I called ls_script so my groovy line became:


 def listOfFiles = "ls_script".execute().text


I did not like calling outside of the original script but it is quick and it works.

If it makes sense for the overall job at hand, there is a wonderful python library called pexpect .  Somehow this great little library very cleanly bypasses the tty issues I mentioned earlier.

Here is a simple use case of pexpect:


 spawnString = 'ssh ' + thisLogin + '@' + thisIP + ' -p ' + thisPort
 foo = pexpect.spawn(spawnString)
 ssh_newkey = 'Are you sure you want to continue connecting'
 i = foo.expect([ssh_newkey, 'password'])
        if i == 0:
            foo.sendline('yes')
            i = foo.expect([ssh_newkey, 'password'])
        if i == 1:
            foo.sendline(thisPassword)
 foo.sendline(' ')
 data = foo.readline()


Checkout the sourceforge page and http://www.noah.org/wiki/pexpect which I believe is the original creator's site with some nice documentation.