操作模式一:(linux)importselectimportsysimportsocketwhileTrue:#监视用户输入和服务器返回的数据
#sys.stdin处理用户输入
#channel是之前创建的通道,用于接收服务器返回信息和发送信息,相当于socket句柄
readable,writeable,error=select.select([channel,sys.stdin,],[],[],1)#只要 channel,stdin,两个句柄其中之一变化就......
if channel inreadable:try:
x=channel.recv(1024)if len(x)==0:print '*** EOF',breaksys.stdout.write(x)
sys.stdout.flush()exceptsocket.timeout:pass
if sys.stdin inreadable:
inp=sys.stdin.readline()
channel.sendall(inp)
操作模式二:(linux)
原始终端模式tty,一个字符发送一次,能有tab补齐等的效果,断开连接之前再切换回标准终端模式,不然堡垒机的tty会有问题。importselectimportsysimportsocketimport termios #只在linux下支持
importtty#获取原tty属性
oldtty =termios.tcgetattr(sys.stdin)try:#为tty设置新属性
#默认当前tty设备属性:
#输入一行回车,执行
#CTRL+C 进程退出,遇到特殊字符,特殊处理。
#这是为原始模式,不认识所有特殊符号
#放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
tty.setraw(sys.stdin.fileno()) #设置为原始终端模式
channel.settimeout(0.0)whileTrue:#监视 用户输入 和 远程服务器返回数据(socket)
#阻塞,直到句柄可读
r, w, e = select.select([channel, sys.stdin], [], [], 1)if channel inr:try:
x= channel.recv(1024)if len(x) ==0:print '*** EOF',breaksys.stdout.write(x)
sys.stdout.flush()exceptsocket.timeout:pass
if sys.stdin inr:
x= sys.stdin.read(1)if len(x) ==0:breakchannel.send(x)finally:#重新设置终端属性
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
操作模式三:(windows)defwindows_shell(chan):importthreading
sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.")defwriteall(sock):whileTrue:
data= sock.recv(256)if notdata:
sys.stdout.write('*** EOF ***')
sys.stdout.flush()breaksys.stdout.write(data)
sys.stdout.flush()
writer= threading.Thread(target=writeall, args=(chan,))
writer.start()try:whileTrue:
d= sys.stdin.read(1)if notd:breakchan.send(d)exceptEOFError:#user hit ^Z or F6
pass记录日志:
也记录了tab(''),显示的不完整,解决思路:根据返回的结果进行处理,比较麻烦。try:
f=open('log','a')whileTrue:if channel inr:try:if len(x)==0:
f.close()if sys.stdin inr:
......
f.write(x)finally:pass