在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格式),而不再使用动态判断,可解决问题。
以上为个人见解,如有问题请指正。
阅读(4350) | 评论(0) | 转发(0) |