现象:
ServerDog的其中一个服务器命令行监控功能是用于监控服务器的各个网卡的流量情况的,以往该功能一直能够正常运行。
但是最近新添加的几台服务器,ServerDog一直无法获取到有效的网络sar -n DEV信息,相关的各项网络数据一直为0。查看ServerDog的日志发现,这几台服务器的命令行输出有异常,其中包含了一些奇怪的字符,如:
ESC[32;22m
ESC[0m
ESC[34;1m
等。
命令行输出中这些字符的出现导致ServerDog对命令行输出的结果解析异常,一开始我以为遇到了字符串编码问题,后来仔细看并不是,因为其中的英文、中文都显示正常。
经过网络查询,得知这些奇怪的字符是Linux终端中的文本颜色控制信息,其中的ESC是一个不可见字符,即ESCAPE控制符。
这就神奇了,因为在ServerDog过去监控的其他服务器上,该命令在服务器的终端,以及java的DumpPTY终端中输出的文本都是纯文本;并且在现在出问题的服务器上,其在服务器的终端下的输出也是没有颜色设置的,但到了java的DumpPTY终端里边,其输出反而包含了文本颜色控制信息。
解决办法:
这个问题的解决思路很简单。
最开始想到的是直接在shell命令行中添加相关参数关闭命令行输出中的颜色控制信息,如:
ls --color=none
然而,这里有两个问题,首先是不同的命令行,其关闭颜色控制信息的选项并不统一,难以标准化、规范化操作,其次是很多命令行甚至不提供或者难以找到关闭输出文本颜色控制信息的选项,例如上文中提到的sar命令行我就没有找到对应的参数选项。
第二种想到的方法是在系统全局下关闭命令行的颜色控制信息输出,但这种方法同样有两个弊端。首先是影响面过大,其次是某些命令行的输出可能是硬编码的,无法通过开关来关闭这类命令行的文本颜色控制信息输出,因此这一方法也被否决。
第三种想到的方法是正则表达式过滤。因为命令行输出中的文本颜色控制信息是符合一定的格式的,经过学习可以很快掌握这种颜色控制信息的格式规范,因此我们可以通过正则表达式来将命令行输出中的这些颜色控制信息移除掉。而实际执行起来也有两种方式:
方式一:
修改执行的命令行,利用sed过滤掉颜色控制信息,如:
sar -n DEV 2 3 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
方式二:
在Java代码中通过正则表达式移除颜色控制字符串:
output.replaceAll("[\\x00-\\x1F\\x7F]\\[([0-9]+;)*[0-9]+m", "");
附录:Linux终端中的文本颜色介绍
shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e
格式如下:
echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"
例如:
echo -e "\033[41;36m something here \033[0m"
其中41的位置代表底色,36的位置是代表字的颜色。
注:
1、字背景颜色和文字颜色之间是英文的";"
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配
例:
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[34m 黄色字 \033[0m”
echo -e “\033[41;33m 红底黄字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
字颜色:30—–37
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m”
字背景颜色范围:40—–47
echo -e “\033[40;37m 黑底白字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
echo -e “\033[42;37m 绿底白字 \033[0m”
echo -e “\033[43;37m 黄底白字 \033[0m”
echo -e “\033[44;37m 蓝底白字 \033[0m”
echo -e “\033[45;37m 紫底白字 \033[0m”
echo -e “\033[46;37m 天蓝底白字 \033[0m”
echo -e “\033[47;30m 白底黑字 \033[0m”
最后面控制选项说明:
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m — \33[37m 设置前景色
\33[40m — \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标