python decode 常见bug修改

环境说明:
       1、服务器IP:192.168.4.x
        2、运行环境:python3
        3、代码目录:/usr/local/jumpserver
        4、程序运行方式:/usr/bin/python3 /usr/local/jumpserver/bin/jumpserver.py start_session
                                     或jump  (已定义别名:alias jump='/usr/local/jumpserver/bin/jumpserver.py start_session')
        5、调用了python下的ssh访问模块paramiko和交互模块interactive,interactive功能通过读取键盘输入命令,并将结果返回到屏幕输出,同时将输入的字符记录并导入到数据库。
 
故障说明及解决方法:
1、在调用ssh_login和interactive.py里,ssh交互执行命令的功能已经实现,就是有点在对上下左右控制键上的小问题:1、在命令行按向上键查看历史命令时,第一次按向上键没有输出显示,但回车键可以正常执行命令   2、在vim编辑状态下上下左右键的处理,有时候会回显A,B,C,D
故障原因:
      本程序最大BUG:
       当读取键盘输入时,方向键会有问题,因为按一次方向键会产生3个字节数据,我的理解是按键一次会被select捕捉一次标准输入有变化,但是我每次只处理1个字节的数据,其他的数据会存放在输入缓冲区中,等待下次按键的时候一起发过去。这就导致了本来3个字节才能完整定义一个方向键的行为,但是我只发过去一个字节,所以终端并不知道我要干什么。所以没有变化,当下次触发按键,才会把上一次的信息完整发过去,看起来就是按一下方向键有延迟。多字节的粘贴也是一个原理。
故障解决:
      解决办法是将输入缓冲区置为0,这样就没有缓冲,有多少发过去多少,这样就不会有那种显示的延迟问题了。          
          stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
          fd = stdin.fileno()
备注:解决方案见https://blog.csdn.net/zlucifer/article/details/70858491
2、Traceback (most recent call last):
  File "/usr/local/jumpserver/bin/jumpserver.py", line 12, in <module>
    excute_from_command_line(sys.argv)
  File "/usr/local/jumpserver/modules/actions.py", line 26, in excute_from_command_line
    action_registers.actions[argvs[1]](argvs[1:])
  File "/usr/local/jumpserver/modules/views.py", line 251, in start_session
    host_choice = input("[(b)back,(q)quit, select host to login]:").strip()
OSError: [Errno 9] Bad file descriptor
故障原因:
      在解决故障1(本程序最大BUG)上产生的一系列新BUG(包括以下全部BUG)
      (1)、 在设置了缓冲区为0后,导致在业务主机和堡垒机之间的标准输入sys.stdin不一致,但尝试了N多方法,也无法还原标准输入;
                    在业务主机上输入exit后,结束SSH登录后,python程序无法识别新的stdin,程序报如上错误;
      (2)、 因python3环境下的标准输入为bytes字节后,读入内存需要decode为unicode编码,保存到文件又需要encode为bytes编码,针对普通字符和汉字产生N多编码问题;
故障解决:
      (1)、临时解决方案:使用try和except方法,将OSError类的报错,强制exit程序(使用pass,coutinue,break等重置、跳出while无法解决)
      (2)、编码解决方案见如下具体故障;
        
3、*** Caught exception: <class 'ValueError'>: can't have unbuffered text I/O
Traceback (most recent call last):
  File "/usr/local/jumpserver/modules/ssh_login.py", line 54, in ssh_login
    interactive.interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 62, in interactive_shell
    posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 77, in posix_shell
    stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
  File "/usr/lib/python3.4/os.py", line 980, in fdopen
    return io.open(fd, *args, **kwargs)
ValueError: can't have unbuffered text I/O
 故障原因:
        因python3默认使用的是str类型对字符串编码,默认使用bytes操作二进制数据流,故在标准输入时,打开方式应为二进制;
故障解决:
                 stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
       同时在读取标准输入时,应转化为str编码:
                 x = stdin.read(1).decode('utf-8',errors='ignore')
 
4、Caught exception: <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode bytes in position 1022-1023: unexpected end of data
Traceback (most recent call last):
  File "/usr/local/jumpserver/modules/ssh_login.py", line 53, in ssh_login
    interactive.interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 61, in interactive_shell
    posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 110, in posix_shell
    x = u(chan.recv(1024))
  File "/usr/local/lib/python3.4/dist-packages/paramiko/py3compat.py", line 143, in u
    return s.decode(encoding)
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 1022-1023: unexpected end of data
故障原因:
       python3环境下,因在interactive交互过程中,标准输出需要转化为str编码,文件中的汉字无法decode;
故障解决:
       使用x = chan.recv(1024).decode('utf-8',errors='ignore')替换原有的 x = u(chan.recv(1024)),即在decode中,如有报错,则忽略;
 
5、'utf-8' codec can't encode character '\udc9b' in position 0: surrogates not allowed
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/CommandNotFound/util.py", line 24, in crash_guard
    callback()
  File "/usr/lib/command-not-found", line 90, in main
    if not cnf.advise(args[0], options.ignore_installed) and not options.no_failure_msg:
  File "/usr/lib/python3/dist-packages/CommandNotFound/CommandNotFound.py", line 265, in advise
    packages = self.getPackages(command)
  File "/usr/lib/python3/dist-packages/CommandNotFound/CommandNotFound.py", line 157, in getPackages
    result.update([(pkg, db.component) for pkg in db.lookup(command)])
  File "/usr/lib/python3/dist-packages/CommandNotFound/CommandNotFound.py", line 85, in lookup
    result = self.db.lookup(command)
  File "/usr/lib/python3/dist-packages/CommandNotFound/CommandNotFound.py", line 41, in lookup
    key = key.encode('utf-8')
UnicodeEncodeError: 'utf-8' codec can't encode character '\udc9b' in position 0: surrogates not allowed
故障原因:
       python3环境下,因在interactive交互过程中,标准输入为bytes字节码,需要转化为str编码,但一个汉字需要3个字节,故原有的x = u(stdin.read(1))会导致汉字无法获取,故报错;
故障解决:
      临时解决方案:x = u(stdin.read(3))
6、Caught exception: <class 'UnicodeEncodeError'>: 'ascii' codec can't encode character '\u4f60' in position 0: ordinal not in range(128)
Traceback (most recent call last):
  File "/usr/local/jumpserver/modules/ssh_login.py", line 53, in ssh_login
    interactive.interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 62, in interactive_shell
    posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
  File "/usr/local/jumpserver/modules/interactive.py", line 126, in posix_shell
    sys.stdout.write(x)
UnicodeEncodeError: 'ascii' codec can't encode character '\u4f60' in position 0: ordinal not in range(128)
故障原因:
     因mac下的ssh访问终端工具iTerm2编码不是utf-8,故有此报错;
故障解决:
     将终端编码更换为utf-8;
 
7、/usr/local/lib/python3.4/dist-packages/pymysql/cursors.py:166: Warning: (1265, "Data truncated for column 'cmd' at row 1")
                        result = self._query(query)
故障原因:
       因输出获取以1024字节,偶尔会出现超过1024字节的这类警告;
故障解决:
        因偶尔出现,暂不影响使用,故此warning暂无处理;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值