1

I am using ssh to log into a camera, scp a tarball over to it and extract files from the tarbal and then run the script. I am having problems with Pexpect, though. Pexpect times out when the tarball is being copied over. It seem's not to wait until it is done. And then it start's doing the same thing with the untar command, The code I have is below:

 ssh_newkey = 'Are you sure you want to continue connecting' copy = pexpect.spawn('ssh [email protected]') i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) if i==0: copy.sendline('yes') i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) if i==1: copy.sendline("service") print 'Password Accepted' copy.expect('service@user:') copy.sendline('su - root') i=copy.expect('Password:') copy.sendline('root') i=copy.expect('#') copy.sendline('cd /tmp') i=copy.expect("#") copy.sendline('scp [email protected]:/home/user/tarfile.tar.gz .') i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) if i==0: copy.sendline('yes') i=copy.expect([ssh_newkey,'password:',pexpect.EOF]) else: pass copy.sendline('userpwd') i=copy.expect('#') copy.sendline('tar -zxvf tarfile.tar.gz bin/installer.sh') i=copy.expect("#") copy.sendline("setsid /tmp/bin/installer.sh /tmp/tarfile.tar.gz > /dev/null 2>&1 &") elif i==2: print "I either got key or connection timeout" else: pass 

Can anyone help find a solution for this?

Thanks

1
  • Can you close the quote @ the 2dn line, so it will print nicer? Commented Jun 16, 2010 at 14:51

2 Answers 2

2

I'm not sure if this is correct, but I'd try setting the timeout to None:

copy = pexpect.spawn('ssh [email protected]', timeout=None) 

According to the source code, pexpect seems to not check the timeout when it's set to None.

Anyway, the reason I'm answering this even though I'm not sure whether it solves your problem is that I wanted to recommend using paramiko instead. I had good experience using it for communication over SSH in the past.

Sign up to request clarification or add additional context in comments.

1 Comment

áš -- I feel a bit silly now, I never thought of that. The timeout is set to 30 seconds and the tarbal takes longer than that to copy over. This work's now. Thanks +1
1

Is there a reason your using pexpect or even paramiko?

if you setup a public/private key then you can just use as a single example:

command = "scp [email protected]:/home/user/tarfile.tar.gz" split_command = shlex.split(command) subprocess.call(split_command) 

Then as per the suggestion above use paramiko to send commands.

you can use the keyfile for that as well:

The following class method will give you a persistent session (although it is untested):

#!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function import os from paramiko import SSHClient, AutoAddPolicy, AuthenticationException, RSAKey from subprocess import call class CommsSuite(object): def __init__(self): self.ssh_client = SSHClient() #-------------------------------------- def _session_send(command): """ Use to send commands over ssh in a 'interactive_session' Verifies session is present If the interactive_session is not present then print the failed command. This may be updated to raise an error, which would probably make more sense. @param command: the command to send across as a string ::TODO:: consider raise exception here as failed session will most likely be fatal. """ if self.session.send_ready(): self.session.send("%s\n" % command) else: print("Session cannot send %s" % command) #-------------------------------------- def _get_persistent_session(_timeout = 5): """ connect to the host and establish an interactive session. @param _timeout: sets the timout to prevent blocking. """ privatekeyfile = os.path.expanduser('~/.ssh/id_rsa')#this must point to your keyfile private_key = RSAKey.from_private_key_file(privatekeyfile) self.ssh_client.set_missing_host_key_policy(AutoAddPolicy()) self.ssh_client.connect(hostname, username = <username>, pkey = private_key, timeout = _timeout) self.transport = self.ssh_client.get_transport() self.session = self.transport.open_session() self.session.exec_command("bash -s") _get_persistent_session() # build a comma seperated list of commands here as a string "[a,b,c]" commands = ["tar -zxvf tarfile.tar.gz bin/installer.sh", "setsid /tmp/bin/installer.sh /tmp/tarfile.tar.gz > /dev/null 2>&1"] # then run the list of commands if len(commands) > 0: for command in commands: _session_send(command) self.session.close()#close the session when done CommsSuite() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.