scp to a remote server using pexpect

user2988577 picture user2988577 · Mar 6, 2014 · Viewed 13k times · Source

I'm trying to learn a little bit on pexpect: in particular I'm trying to copy a file from my laptop to a remote server. I'm experiencing a weird behaviour: more or less the same code works if I write it line by line but it won't if I run it as a script. Here is what I write line-by-line:

child = pexpect.spawn('scp pathdir/file.ext username@hostname:pathdir')
r=child.expect ('assword:')
r

it returns 0 and I finish the job with the password

child.sendline ('password')

When I do ssh to the server I found my file there. So I collect all the steps in a script; it exits without errors, but the file it was not copied... why? But more importantly, how can I fix that?

Here is the script:

child = pexpect.spawn('scp pathdir/file.ext username@hostname:pathdir')
r=child.expect ('assword:')
print r
if r==0:
    child.sendline ('password')
child.close()

I'm not sure how pexpect works so I print r to be sure it is 0. And it is.

Answer

v1h5 picture v1h5 · Oct 15, 2014

I faced the "same" problem recently. Here's how I did it. I hope this will definitely help you.

Your question : I'm not sure how pexpect works so I print r to be sure it is 0. And it is.

Yes it is zero.

Try the code below :

    try:
        var_password  = "<YOUR PASSWORD>" Give your password here
        var_command = "scp pathdir/file.ext username@hostname:pathdir"
        #make sure in the above command that username and hostname are according to your server
        var_child = pexpect.spawn(var_command)
        i = var_child.expect(["password:", pexpect.EOF])

        if i==0: # send password                
                var_child.sendline(var_password)
                var_child.expect(pexpect.EOF)
        elif i==1: 
                print "Got the key or connection timeout"
                pass

    except Exception as e:
        print "Oops Something went wrong buddy"
        print e

child.expect can accept more than one arguments. In such case you have to send those arguments in form of list. In above scenario, if output of pexpect.spawn is "password:" then i will get 0 as output and if EOF is encountered instead of "password" then the value of i will be 1.

I hope this would clear your doubt. If not, then let me know. I will try to enhance the explanation for you.