python3 中的 Pexpect interact() 异常
Pexpect interact() exception in python3
我正在学习 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
用谷歌搜索了这个问题,但实际上与 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
一起工作的帮助,我将不胜感激
谢谢。
更新
我面临的新问题是,在我捕获输出的日志文件中看不到 ps 等具有较大输出的文件目录的命令输出。我尝试使用 "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 命令的输出在日志文件中看不到。
我找到了解决您问题的方法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()
我想我面临着同样的问题,但方式不同。我希望日志文件转到一个文件。根据我打开它的方式,我会收到不同的错误。看:
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
函数调用的编码参数,但没有解决问题。
我 运行 python 3.6.9 Ubuntu 18.04.
我正在学习 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
用谷歌搜索了这个问题,但实际上与 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
一起工作的帮助,我将不胜感激谢谢。
更新我面临的新问题是,在我捕获输出的日志文件中看不到 ps 等具有较大输出的文件目录的命令输出。我尝试使用 "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 命令的输出在日志文件中看不到。
我找到了解决您问题的方法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()
我想我面临着同样的问题,但方式不同。我希望日志文件转到一个文件。根据我打开它的方式,我会收到不同的错误。看:
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
函数调用的编码参数,但没有解决问题。
我 运行 python 3.6.9 Ubuntu 18.04.