我正在学习Python,如果我的问题很天真,请道歉。
我在我的脚本中使用pexpect
interact()
,它正在使用python2.7。但是当我使用python3或python3.5时,我得到以下错误:
Traceback (most recent call last):
File "ap_access.py", line 73, in <module>
child.interact()
File "/usr/local/lib/python3.5/dist-packages/pexpect/pty_spawn.py", line 745, in interact
self.__interact_copy(escape_character, input_filter, output_filter)
File "/usr/local/lib/python3.5/dist-packages/pexpect/pty_spawn.py", line 784, in __interact_copy
self._log(data, 'read')
File "/usr/local/lib/python3.5/dist-packages/pexpect/spawnbase.py", line 121, in _log
self.logfile.write(s)
TypeError: write() argument must be str, not bytes
关于此问题的Google搜索,但实际上没有与interact()相关但没有获得太多信息。
# Script to log into the device and execute the required shell commands.
log_file = open('logfile.txt', 'w')
for ip in list_of_IP_addresses:
ip1=str(ip)
child = pexpect.spawnu('ssh '+username+'@'+ip1, log_file)
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==0:
child.sendline('yes')
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==1:
print("Entering the Username")
child.sendline(username)
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==2:
print("Entering the credentials")
child.sendline(password)
if code==3:
print ("Please check for reachability for ip", ip1)
sys.exit()
if code==4:
print ("Looks like there is an error")
sys.exit(0)
if code==5:
print ("Timeout in accessing or logging into ", ip1)
sys.exit(0)
child.interact()
如果可以获得有关如何使pexpect interact()与python3.x一起使用的帮助,我将不胜感激
谢谢。
UPDATE我面临的新问题是在我捕获输出的日志文件中无法看到输出命令如ps,cat输出较大的文件。我尝试使用“setwinsize”设置winsize,将maxreadsize设置为更大的值,但没有任何改变。
def log_separation():
sep_file = 'Device_LOG_{}.log'.format(date.today())
child.logfile = open(sep_file, "a")
with open(sep_file, 'a+') as log_sep:
log_sep.write('\n'+'\n')
def mem_cpu():
mem_file = 'Device_LOG_{}.log'.format(date.today())
with open(mem_file, 'a+') as cpu:
cpu.write(str(datetime.datetime.now())+'\n') cpu.write('########################################################'+'\n')
child.sendline('top -n 1')
child.expect('#')
log_separation()
child.sendline('cat /proc/meminfo')
log_separation()
child.expect('#')
child.sendline('cat /proc/slabinfo')
log_separation()
child.expect('#')
child.sendline('cat /proc/tasklets')
log_separation
child.expect('#')
child.sendline('free')
log_separation()
child.expect('#')
child.sendline('ps axww')
log_separation()
child.expect('#')
child.sendline('exit')
# Gets the set of all IP addresses in the given range
list_of_IP_addresses = get_IP_address(ip_addr_lower, ip_addr_upper)
#Opening a file to write the error logs to
log_file = open('logfile.txt', 'w')
with open('Device_Access_log.log', 'w+') as f:
# Script to log into the devices and excute the required shell commands.
for ip in list_of_IP_addresses:
ip1=str(ip)
child = pexpect.spawn('ssh '+username+'@'+ip1, logfile=log_file)
child.logfile_read = sys.stdout
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==0:
child.sendline('yes')
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==1:
print('Entering the Username')
child.sendline(username)
code = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'Please login: ', 'password :', 'No route to host', pexpect.EOF, pexpect.TIMEOUT])
if code==2:
print('Entering the credentials')
child.sendline(password)
mem_cpu()
stats_file = 'Device_LOG_{}.log'.format(date.today())
with open(stats_file, 'a+') as eol:
eol.write('############################### End of log for Device '+ip1+' ###############################################'+'\n')
eol.write('########################################################################################################'+'\n')
if code==3:
print ('Ip address error', ip1)
f.write('No route to host '+ip1+'\n')
if code==4:
print ('Error connecting to ', ip1)
f.write('Error connecting to '+ip1+'\n')
if code==5:
print ('Timeout in accessing or logging into ', ip1)
f.write('Timeout in accessing or logging into '+ip1+'\n')
我可以看到输出直到“free”,ps命令的输出在日志文件中看不到。
答案 0 :(得分:1)
我找到了问题的解决方案here:如果您将代码的开头更改为:
for ip in list_of_IP_addresses:
ip1=str(ip)
child = pexpect.spawnu('ssh '+username+'@'+ip1, logfile=sys.stdout.buffer) # <-- add the logfile keyword here and use sys.stdout.buffer (byte mode) instead of sys.stdout
##child.logfile = sys.stdout #<-- comment out this line
它应该工作。注意:我无法完整地测试您的代码。 if
个案例对我不起作用,因为我使用ssh键。另外,对我来说键盘回声重复每个字母三次。无论如何,我希望这会对你有所帮助。
修改强>:
我没有找到关于输入类型的三重回显的任何内容,但它与将stdout
设置为日志文件这一事实有关。如果您创建了一个日志文件,问题就会消失:
mylogfile = open('logfile.txt', 'wb')
for ip in list_of_IP_addresses:
ip1=str(ip)
child = pexpect.spawnu('ssh '+username+'@'+ip1, logfile=mylogfile)
child.interact()
答案 1 :(得分:0)
我认为我面临同样的问题,但是方式不同。我希望日志文件转到文件。根据我打开它的方式,我会得到一个不同的错误。看哪:
with open("ssh_run.log", "ab") as logfile:
print( f"Connecting to {self.pxe_user}@{self.pxe_server_ipv4}\n{cmd_2_ssh}" )
y5: Tuple = pexpect.run( cmd_2_ssh, \
# (?i) turns on case-insensitive mode
events={"(?i)password: ": self.pxe_passwd + "\n"}, \
withexitstatus = True, logfile=logfile,
timeout = 20 )
我以“ ab”模式打开了日志文件。我收到的错误消息是:
TypeError: a bytes-like object is required, not 'str'
但是,如果我将模式更改为“ a”或“ at”而不是“ ab”,则会得到:
TypeError: write() argument must be str, not bytes
我还尝试了open
函数调用的编码参数,但这并不能解决问题。
我正在Ubuntu 18.04上运行python 3.6.9。