描述
在linux中获取进程cmdline时遇到隐藏符号问题,如下:
1
2
3
4
5
6
7
8
9
10
|
[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] |
这样的数据直接在终端显示是没问题的,但是记录到日志中,变成:
1
|
{ "level" : "info" , "ts" : 1650267870.4412727 , "caller" : "ssh/manager.go:78" , "msg" : "/usr/sbin/sshd\u0000-D\u0000" } |
或
1
|
/usr/sbin/sshd-D |
而系统实际的进程启动参数为:
1
|
root 45 1 0 Jan12 ? 00 : 01 : 57 /usr/sbin/sshd -D |
此时,如果查看切片的内容,可以看到包含了无法显示的ascii码,空格码点变成了0(我们要做的是把这个替换为十进制32对应真实的空格)
1
|
[] byte : [ 47 117 115 114 47 115 98 105 110 47 115 115 104 100 0 45 68 0 ] |
解决方法一,手动处理
这里只贴上主要代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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 err } newByte := 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库(推荐)
1
2
3
4
5
6
7
8
9
|
// ...略 newByte := bytes.ReplaceAll([] byte (cmdline), [] byte { 0 }, [] byte { 32 }) newByte = bytes.TrimSpace(newByte) newResult := string (newByte) if len (newResult) > 64 { newResult = newResult[: 64 ] } e.Pids[pid].CMDLine = newResult |
到此这篇关于golang替换无法显示的特殊字符(\u0000, \000, ^@)的文章就介绍到这了,更多相关golang替换字符内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.51cto.com/sndapk/5216291