I have finally have my python pexpect script working except for the most important part updating the date! I am able to SSH in the box but my second command does not execute properly. I have been banging my head on the wall trying to figure out why. I have checked the output of the sting and it should be working based on whats coded. I am not a expert when it comes to python or pexpect so I am in need of a bit of help figuring out why my time is not updating.
my original code:
list = ["089"]
sn = 0
ssh_new_conn = 'Are you sure you want to continue connecting'
class ThreadClass(threading.Thread):
def __init__(self, index):
super(ThreadClass, self).__init__()
self.index = index
def run(self):
sn = storelist[self.index]
#easterndate = (currenttime + datetime.timedelta(0, 3600))
#easterndate = easterndate
est = timezone('US/Eastern')
cst = timezone('US/Central')
#currenttime = (datetime.now())
currenttime = cst.localize(datetime.now())
#easterndate = (currenttime + timedelta(0, 3600))
#easterndate = easterndate.strftime("%a %b %d %H:%M:%S %Z %Y")
easterndate = currenttime.astimezone(est).strftime("%a %b %d %H:%M:%S %Z %Y")
command1 = "/usr/bin/ssh %(username)s@%(hostname)s" % locals()
command2 = " sudo date -s\"%(easterndate)s\"" % locals()
command3 = " sudo date -s\"%(currenttime)s\"" % locals()
now = datetime.now()
#central
if sn == "073" or sn == "066" or sn == "016": #or sn == "022":
p = pexpect.spawn((command1 + command3), timeout=360)
#eastern
else:
print(command1 + command2)
p = pexpect.spawn((command1 + command2), timeout=360)
# Handles the 3 possible connection outcomes:
# a) Ssh to the remote host for the first time, triggering 'Are you sure you want to continue connecting'
# b) ask you for password
# c) No password is needed at all, because you already have the key.
i = p.expect([ssh_new_conn,'[pP]assword:',pexpect.EOF])
print ' Initial pexpect command output: ', i
if i == 0:
# send 'yes'
p.sendline('yes')
i = p.expect(['[pP]assword:',pexpect.EOF])
print 'sent yes. pexpect command output', i
if i == 0:
# send the password
print "logging into box %(sn)s" % locals()
p.sendline(password)
print "login successful"
print "Setting the time..."
elif i == 1:
# send the password
print "logging into box %(sn)s" % locals()
p.sendline(password)
print "login successful"
print "Setting the time..."
p.close()
elif i == 2:
print "pexpect faced key or connection timeout"
pass
print p.before
for i in range(len(list)):
t = ThreadClass(i)
t.start()
New Code:
class ThreadClass(threading.Thread):
def __init__(self, index):
super(ThreadClass, self).__init__()
self.index = index
def run(self):
try:
sn = storelist[self.index]
username = raw_input('username: ')
password = raw_input('password: ')
hostname = "[hostname]"
est = timezone('US/Eastern')
cst = timezone('US/Central')
#currenttime = (datetime.now())
currenttime = cst.localize(datetime.now())
#easterndate = (currenttime + timedelta(0, 3600))
#easterndate = easterndate.strftime("%a %b %d %H:%M:%S %Z %Y")
easterndate = currenttime.astimezone(est).strftime("%a %b %d %H:%M:%S %Z %Y")
ssh = pxssh.pxssh()
print(hostname + " " + username + " " + password)
ssh.login(hostname, username, password)
if sn == "073" or sn == "066" or sn == "016": #or sn == "022":
ssh.sendline ('date') # run a command
ssh.prompt() # match the prompt
print(s.before) # print everything before the prompt.
ssh.sendline ('sudo date -s\"%(currenttime)s\"' % locals()) # run a command
ssh.expect('(?i)password.*:') # match password prompt for sudo
ssh.sendline(password)
ssh.prompt()
print(s.before)
ssh.logout()
else:
ssh.sendline ('date') # run a command
ssh.prompt() # match the prompt
print(s.before) # print everything before the prompt.
ssh.sendline ('sudo date -s\"%(easterndate)s\"' % locals()) # run a command
ssh.expect('(?i)password.*:') # match password prompt for sudo
ssh.sendline(password)
ssh.prompt()
print(s.before)
ssh.logout()
except pxssh.ExceptionPxssh as e:
print(e)
for i in range(len(storelist)):
t = ThreadClass(i)
t.start()
New Error I am getting:
Traceback (most recent call last):
File "./sshtest.py", line 8, in <module>
s.login (hostname, username, password)
File "/usr/lib/python2.6/dist-packages/pxssh.py", line 243, in login
if not self.synch_original_prompt():
File "/usr/lib/python2.6/dist-packages/pxssh.py", line 134, in synch_original_prompt
self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt
File "/usr/lib/python2.6/dist-packages/pexpect.py", line 824, in read_nonblocking
raise TIMEOUT ('Timeout exceeded in read_nonblocking().')
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
SOLUTION TO ERROR
I figured out the solution to the error I was getting. Due to a known bug I had to add the following lines to usr/lib/python.2.6/dist-packages/pxssh.py:
self.sendline() #line 134
time.sleep(0.5) #line 135
self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt
Python update () function in set adds elements from a set (passed as an argument) to the set. Here set1 is the set in which set2 will be added. Parameters : Update () method takes only a single argument. The single argument can be a set, list, tuples or a dictionary.
Pexpect is a Python library for spawning child processes and controlling them automatically. Pexpect can be used to automate interactive applications such as SSH, FTP, password, telnet, etc. Pexpect works by spawning child processes and responding to expected patterns.
Parameters : Update () method takes only a single argument. The single argument can be a set, list, tuples or a dictionary. It automatically converts into a set and adds to the set. Return value : This method adds set2 to set1 and returns nothing.
Update/Upgrade Python Package To Specific Version with Pip By default, the specified package will be updated or upgraded to the latest version. But this can be a problem if we need a specific version of the Python package. This generally occurs where some software depends on and supports a specific version of the Python package.
SOLUTION TO ERROR
I figured out the solution to the error I was getting. Due to a known bug I had to add the following lines to usr/lib/python.2.6/dist-packages/pxssh.py:
self.sendline() #line 134
time.sleep(0.5) #line 135
self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt
You should probably handle the sudo password prompt (+ -t
ssh option to get a tty) and use p.expect(EOF)
before p.close()
to avoid killing the child process prematurely.
Here's an example based on pexpect docs:
import pxssh
try:
s = pxssh.pxssh()
s.login (hostname, username, password)
s.sendline ('date') # run a command
s.prompt() # match the prompt
print(s.before) # print everything before the prompt.
s.sendline ('sudo date') # run a command
s.expect('(?i)password.*:') # match password prompt for sudo
s.sendline(password)
s.prompt()
print(s.before)
s.logout()
except pxssh.ExceptionPxssh as e:
print(e)
You could also try fabric
:
# fabfile.py
from fabric.api import run, sudo
def date():
run('date')
sudo('date')
Usage:
$ fab -H localhost,user@host date
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With