问题
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
回答1:
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
回答2:
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
回答3:
To any other poor souls like me stuck with python 2.6 in 2019 and not wanting to hack their site-packages, I was able to fix this issue with setting maxread to 1 in the constructor.
pxssh.pxssh(maxread=1)
来源:https://stackoverflow.com/questions/15911290/python-pexpect-sshing-then-updating-the-date