Lets say I want to extract current State
(D/R/S/T/Z) and command Name
from processes with given PID
.
For example I have this code:
pids=$(pidof firefox) #returns all PID-s of firefox processes (random example)
for v in ${pids[*]}
do
echo "PID: $v" #here I also want to write status and name of the command (PID, Name, Status)
done
more /proc/$$/status
returns
Name: bash
Umask: 002
State: S (sleeping)
....
Pid: 3234
...
From all that information I only need some. I want to know how to extract desired property (Name
, Status
,...) from proc
.
CodePudding user response:
Using awk
to pull out the Name
and State
:
$ awk '$1=="Name:"{name=$2;next}$1=="State:"{print name,$2;exit}' /proc/$$/status
bash S
Fixing issues with OP's code and pulling the awk
script into the mix:
pids=( $(pidof firefox) #returns all PID-s of firefox processes (random example) )
for v in "${pids[*]}"
do
read -r name state < <(awk '$1=="Name:"{name=$2;next}$1=="State:"{print name,$2;exit}' /proc/${v}/status)
echo "PID: ${v} / Name: ${name} / State: ${state}"
done
Running against OP's single example this should generate:
PID: 3234 / Name: bash / State: S
CodePudding user response:
To avoid repeated calls to awk
in the possibility that you have a lot of elements (unlikely, but hey, maybe it's a server of something...), but mostly as an exercise...
$: awk '/^Pid:/{ pid[FILENAME]=$2 } /^Name:/{ name[FILENAME]=$2 } /^State:/{ state[FILENAME]=$2 } END{ for (k in pid) printf "PID:\t%s\tName:\t%s\tState:\t%s\n", pid[k],name[k],state[k] }' $( sed -E 's,(.*),/proc/\1/status,' <(pidof firefox) )
PID: 1619 Name: firefox State: S
PID: 1620 Name: firefox State: S
One-liners are ugly - breaking it out -
(I don't actually have pidof or firefox on this laptop, so for full transparency I made a file with a couple pids and used cat lst
instead of pidof firefox
, so will just use that below.)
$: cat lst # the file
1619
1620
$: sed -E 's,(.*),/proc/\1/status,' <(cat lst) # the status inputs
/proc/1619/status
/proc/1620/status
$: awk '/^Pid:/{ pid[FILENAME]=$2 }
/^Name:/{ name[FILENAME]=$2 }
/^State:/{ state[FILENAME]=$2 }
END{ for (k in pid) printf "PID:\t%s\tName:\t%s\tState:\t%s\n", pid[k],name[k],state[k] }
' $( sed -E 's,(.*),/proc/\1/status,' <(cat lst) )
PID: 1619 Name: mintty State: S
PID: 1620 Name: bash State: S