我正在运行一条顶层命令,希望将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值为十六进制。所有其他信息都需要保留。
答案 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之后,在循环中修改的过程和变量将不存在。正如我所展示的,基本重定向不会导致子进程。