首页 > 解决方案 > How to convert PID values returned by top command into Hex?

问题描述

I am running a top command and would like the PID decimal values converted to corresponding hexadecimal values

I am trying to capture the JAVA sub-processes or threads spawned by a JVM process as part of standard diagnostics procedure to troubleshoot problems with application server instance such as WebLogic.

The diagnostics include running few commands such as top, lsof, jcmd to capture heap/thread dumps etc. The thread dump gives a list of threads stacks there are currently running on that server. Each thread is identified by its "nid" which is in hexadecimal.

On the other hand, the top command out gives you list a LWP(light weight processes) that are running on that server sorted by CPU/memory usage. I would like the PIDs returned as hexadecimal values in the top command output. One can then isolate the thread in the thread stack dump having a nid which matches the hex value.

top -Hbn3 -p 10258 |sed -n '/PID/,/^$/p' | awk '{print $1}' | sed '/PID/d' > pids.txt

( echo "obase=16" ; cat pids.txt ) | bc

top -Hbn3 -p 10258 returns all those PIDS spawned by process id 10258. The results are captured thrice. See -n3 option given to top command.

Using combination of sed and awk, I managed to extract the first column 'PID" and convert the values to hexadecimal. But I want all the original information returned by the top command. In other words, CPU/Mem usage columns timestamp etc. Only the PID column needs to be in hexadecimal

Actual Results:

$ top -Hbn3 -p 17941
top - 16:47:31 up 267 days, 19:09,  1 user,  load average: 0.13, 0.03, 0.01
Tasks:  88 total,   0 running,  88 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.8%us,  0.5%sy,  0.0%ni, 98.6%id,  0.1%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   3925316k total,  3671784k used,   253532k free,   169504k buffers
Swap:  8388604k total,   214948k used,  8173656k free,  1482452k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
18186 dsadmwl   20   0 2313m 787m  11m S  2.0 20.6  82:17.19 java
17941 dsadmwl   20   0 2313m 787m  11m S  0.0 20.6   0:00.00 java
17943 dsadmwl   20   0 2313m 787m  11m S  0.0 20.6   0:01.25 java

I expect the PID values to be hexadecimal. All other information needs to retained.

标签: linuxshell

解决方案


以下 bash 脚本一次读取一行输出,如果以一系列数字开头,则将它们转换为十六进制。所有其他信息都直接反映。

#!/bin/bash
while read -r zLine || [ -n "$zLine" ]; do
 declare zDeci="$(sed -nE 's/^([0-9]*).*/\1/p' <<< "$zLine")"
 [ -n "$zDeci" ] \
  && printf '%x%s\n' "$zDeci" "${zLine:${#zDeci}}" \
  || printf '%s\n' "$zLine"
done < <(your-command-which-makes-output)

笔记:

  • 它不会影响您,但很高兴知道 read 会修剪每行上的前导和尾随空格。

  • || 如果您的输出以换行符结尾,则 [ -n "$zLine" ] 是不必要的,但是即使成功读取文件之前的字符,当找到文件结尾时,读取也会出错。

  • <(command) 使 bash 创建一个命名管道并将命令的标准输出分配到该管道中。然后 Bash 将 <(command) 脚本文本替换为管道名称。这可以消除,您可以手动将输出通过管道传输到此脚本中。

  • 它不适用于此处,但“编写 your-command-which-makes-output | while ... done”并不是一个好主意,因为管道将导致 bash 将 while 作为子进程启动,并且在之后循环将不存在。我演示的基本重定向不会导致子进程。


推荐阅读