如何将top命令返回的PID值转换为十六进制?

时间:2019-03-27 17:06:45

标签: linux shell

我正在运行一条顶层命令,希望将PID十进制值转换为相应的十六进制值

我试图捕获由JVM进程产生的JAVA子进程或线程,作为标准诊断过程的一部分,以对应用程序服务器实例(例如WebLogic)的问题进行故障排除。

诊断包括运行一些命令,例如top,lsof,jcmd,以捕获堆/线程转储等。线程转储提供了该服务器上当前正在运行的线程堆栈的列表。每个线程都以十六进制的“ nid”标识。

另一方面,top命令可以列出按服务器CPU /内存使用情况排序的LWP(轻量级进程),该进程在该服务器上运行。我希望在顶部命令输出中以十六进制值返回的PID。然后可以隔离线程堆栈转储中具有与十六进制值匹配的nid的线程。

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返回由进程ID 10258产生的所有那些PIDS。结果被捕获三次。请参阅为top命令提供的-n3选项。

使用sed和awk的组合,我设法提取了第一列“ PID”并将其值转换为十六进制。但是我希望top命令返回的所有原始信息都正确,换句话说,CPU / Mem的使用情况列为时间戳记等等。只有PID列必须为十六进制

实际结果:

$ 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

我希望PID值为十六进制。所有其他信息都需要保留。

1 个答案:

答案 0 :(得分:1)

以下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)

注意:

  • 它不会影响您,但是很高兴知道读取会修剪每行的开头和结尾空白。

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

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

  • 它不适用于此处,但“用脚本编写your-command-makes-output | while ... done”不是一个好主意,因为管道将导致bash在儿童时期启动while之后,在循环中修改的过程和变量将不存在。正如我所展示的,基本重定向不会导致子进程。