Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141231
  • 博文数量: 30
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 134
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-21 12:40
个人简介

努力奔跑!

文章分类

全部博文(30)

文章存档

2017年(1)

2016年(3)

2015年(3)

2014年(23)

我的朋友

分类: LINUX

2017-09-21 10:44:45

在linux系统中top指令显示中文的时候会是乱码,而ps指令则显示正常。
接下来分析具体的原因:
1,首先top指令和ps指令都属于工具包procps,top指令和ps指令都是使用的相同的readproc函数获取的proc下进程下的cmdline字段。
cmdline中存储的字段不是简单的string,而是一种string vector格式,这种格式的字段的读取需要使用特殊的函数。
源码中的函数是:escape.c中的escape_command()函数。,继续跟踪函数可发现在函数escape_str()中,有一段为
nl_langinfo(CODESET),这个函数的作用是获取本系统使用的语言的编码。
2.就在nl_langinfo()函数执行后,发现,top指令的返回值并不是UTF-8的默认格式,而ps指令返回的是UTF-8的默认格式。
所以这是导致top显示中文乱码的主要原因。
3.在ps源码main()函数的开始部分我们发现这样的语句
#if (__GNU_LIBRARY__ >= 6)
  setlocale (LC_CTYPE, "");
#endif
此处设置了该函数使用系统本身的字符编码,设置此处后,nl_langingo()函数获取的内容一般就是linux默认的UTF-8,
4.在top的源码中没有发现此设置,因此这导致了top在使用escape_command()函数解析cmdline中的内容的时候使用了错误的编码格式,因此导致中文显示乱码。
次问题可视作procps工具包的一个小问题,如果使用已经提供的编译好的top指令则无法解决此问题,除非使用源码修改后自己编译,
方法1,在top.c 的main()函数开始的地方添加
#if (__GNU_LIBRARY__ >= 6)
  setlocale (LC_CTYPE, "");
#endif
方法2,直接在escape.c中函数escape_str()中的
#if (__GNU_LIBRARY__ >= 6)
  static int utf_init=0;
  
  if(utf_init==0){
     /* first call -- check if UTF stuff is usable */
     char *enc = nl_langinfo(CODESET);
     utf_init = enc && strcasecmp(enc, "UTF-8")==0 ? 1 : -1;
  }
  if (utf_init==1)
     /* UTF8 locales */
     return escape_str_utf8(dst, src, bufsize, maxcells);
#endif
此处直接设置编码格式为UTF-8 (一般linux都会使用utf-8格式),而不再使用动态判断,可解决问题。
以上为个人见解,如有问题请指正。



阅读(4097) | 评论(0) | 转发(0) |
0

上一篇:Linux启动过程详解

下一篇:没有了

给主人留下些什么吧!~~