相逢意气为君饮,系马高楼垂柳边。这篇文章主要讲述golang替换无法显示的特殊字符u0000, 00, ^@相关的知识,希望能为你提供帮助。
描述【golang替换无法显示的特殊字符u0000, 00, ^@】在linux中获取进程cmdline时遇到隐藏符号问题,如下:
[root@vm010066016161 /root]
#cat /proc/45/cmdline
/usr/sbin/sshd-D
[root@vm010066016161 /root]
#cat /proc/45/cmdline -A
/usr/sbin/sshd^@-D^@
[root@vm010066016161 /root]
#cat /proc/45/cmdline | sed -n l
/usr/sbin/sshd\\000-D\\000$
[root@vm010066016161 /root]
这样的数据直接在终端显示是没问题的,但是记录到日志中,变成:
"level":"info","ts":1650267870.4412727,"caller":"ssh/manager.go:78","msg":"/usr/sbin/sshd\\u0000-D\\u0000"
或
/usr/sbin/sshd-D
而系统实际的进程启动参数为:
root4510 Jan12 ?00:01:57 /usr/sbin/sshd -D
此时,如果查看切片的内容,可以看到包含了无法显示的ascii码,空格码点变成了0(我们要做的是把这个替换为十进制32对应真实的空格)
[]byte: [47 117 115 114 47 115 98 105 110 47 115 115 104 100 0 45 68 0]
解决方法一,手动处理这里只贴上主要代码
cmd := fmt.Sprintf("cat /proc/%s/cmdline", pid)
cmdline, _, err := e.SSHManager.Run(cmd)
if err != nil
e.logger.Error(fmt.Sprintf("pid(%s) CMDLine error[%s]", pid, err.Error()))
return errnewByte := make([]byte, 0)
for _, b := range []byte(cmdline)
if b == 0//小于32的字符都可以以这样的方式处理,本次只处理0
newByte = append(newByte, 32)
else
newByte = append(newByte, b)newResult := strings.TrimSpace(string(newByte)) //结果的空格不需要
解决方法二,使用bytes库(推荐)
// ...略
newByte := bytes.ReplaceAll([]byte(cmdline), []byte0, []byte32)
newByte = bytes.TrimSpace(newByte)
newResult := string(newByte)if len(newResult) >
64
newResult = newResult[:64]e.Pids[pid].CMDLine = newResult
推荐阅读
- 最近遇到的一个库&表字符集大坑
- samba 案例
- JVS快速开发框架产品介绍(V2.1.3)
- pg快速入门--权限管理
- 手把手实践腾讯云COS对象存储的上传
- BigTable的开源实现(HBase)
- kettle庖丁解牛第2篇之初识kettle
- C#/VB.NET 实现Word和ODT文档相互转换
- 在vCenter上更新证书后,Delivery Controller无法联系vCenter Server