Reputation: 37
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.
Upvotes: 0
Views: 2312
Reputation: 582
The following bash script reads the output one line at a time and if begins with a sequence of digits, converts them to hex. All other information is directly reflected.
#!/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)
Notes:
It does not affect you, but it is good to know that read trims leading and trailing white space on each line.
The || [ -n "$zLine" ] is unnecessary if your output ends with a newline, but read will error when end of file is found even if characters preceding it were successfully read.
The <(command) causes bash to create a named pipe and assigns standard output from the command into that pipe. Bash then replaces the <(command) script text with the name of the pipe. This could be eliminated and you could manually pipe the output into this script.
It does not apply here, but is NOT a good idea to "script your-command-which-makes-output | while ... done" because the pipe will cause bash to launch the while as a child process and variables modified in the loop will not exist afterward. Basic redirection as I demonstrated does not cause a child process.
Upvotes: 1