View previous topic :: View next topic |
Author |
Message |
Zucca Moderator
Joined: 14 Jun 2007 Posts: 3686 Location: Rasi, Finland
|
Posted: Wed Jul 19, 2023 8:46 am Post subject: Parseable format out of ps -commands (procps vs. busybox) |
|
|
I've started a new topic here as it thought it needed its own.
geki wrote: | I played a bit with my ps tools from busybox and procps-ng. I recommend to use args over comm to get the process command in full length. You can set the width of the columns of the output of ps by setting its header name. :o
Code: | $ busybox ps -Ao user=ThisIsmYLongUserHeader,pid,tty,args | and Code: | $ ps -Ao user=ThisIsmYLongUserHeader,pid,tty,args |
| I'd use exe but busybox ps doesn't support it.
Your solution is almost perfect (although a bit hacky), but the tty column (which is important to me) differs. I could process the output and make it work. But here's the last thing I wish both ps command could do: seperate columns with tab.
It would be much easier to process. I know I love tsv format. :D
Meanwhile I've created this slow beast: Code: | #!/bin/sh
find /proc -regex '^/proc/[0-9][0-9]*' 2> /dev/null | while read proc
do
rp="$(realpath "${proc}/exe" 2> /dev/null)"
if [ "$rp" != "${proc}/exe" ] && [ -e "${proc}/loginuid" ]
then
unset uid stdin
# Reading the content of loginuid will give "wrong" uid sometimes
uid="$(stat -c '%u'$'\t''%U' "${proc}/loginuid")"
stdin="$(realpath "${proc}/fd/0" 2> /dev/null)"
printf '%s\t%s\t%s\t%s\n' "${proc##*/}" "${uid}" "${stdin:-'N/A'}" "${rp}"
fi
done
| Crawling trough /proc is even worse hack, but I can get out neat tsv.
Also this is so slow (compared to each ps -command) that monitoring of processes is quite a heavy task. For one time listing, it's fine I guess. _________________ ..: Zucca :..
My gentoo installs: | init=/sbin/openrc-init
-systemd -logind -elogind seatd |
Quote: | I am NaN! I am a man! |
|
|
Back to top |
|
|
Zucca Moderator
Joined: 14 Jun 2007 Posts: 3686 Location: Rasi, Finland
|
Posted: Wed Jul 19, 2023 6:29 pm Post subject: |
|
|
I managed make this "shell ps" quite faster with awk passing contents of proc to start via xargs.
And oh boy I once again stumbled into incompatibilities with few common tools. Code: | #!/bin/sh
if [ "$1" != 'awk' ]
then
find /proc -maxdepth 1 -mindepth 1 -regex '^/proc/[0-9][0-9]*' 2> /dev/null | while read proc
do
rp="$(realpath "${proc}/exe" 2> /dev/null)"
if [ "$rp" != "${proc}/exe" ] && [ -e "${proc}/loginuid" ]
then
# The line below will give uid of the user who started the process,
# not the user currently running it. Also root uid becomes 2^32-1.
#read uid < "${proc}/loginuid"
unset uid stdin
# This line however will work as intended.
uid="$(stat -c '%u'$'\t''%U' "${proc}/loginuid")"
# A hacky way (?) to get the tty.
# Really gets the tty where the process receives input (stdin).
stdin="$(realpath "${proc}/fd/0" 2> /dev/null)"
if [ "${stdin:$((${#str}-1)):1}" = ']' ]
then
stdin="pipe:${stdin##*/pipe:}"
fi
printf '%s\t%s\t%s\t%s\n' "${proc##*/}" "${uid}" "${stdin:-'N/A'}" "${rp}"
fi
done
else
# This may be possible to do with single awk...
# We need to avoid find's -exec +, since findutils' find doesn't support -exec command "{}/foo".
# Meaning {} needs to be "alone". Stangely enough busybox find supports this.
# We call awk to run two separate 'xargs' which in turn run 'stat'.
find /proc -maxdepth 1 -mindepth 1 -regex '^/proc/[0-9][0-9]*' \
| awk -v tab=$'\t' '{print $0 "/exe" | "xargs stat -c \"%u" tab "%U" tab "%N\""; print $0 "/fd/0" | "xargs stat -c \"%N\""}' 2> /dev/null \
| awk -v sg="'" -v FS=$'\t' -v OFS=$'\t' '
function parsepid(p) {
match(p,/\/[0-9]+\//)
return substr(p,RSTART+1,RLENGTH-2)
}
{
if (match($3,/-> .+$/)) {
# Since busybox awk does not support nested arrays
# we need to juggle around with several, one-dimensional, arrays
S=RSTART
L=RLENGTH
pid=parsepid($3)
procs[pid]=substr($3,S+4,L-5)
uids[pid]=$1
users[pid]=$2
} else if (match($1,/-> .+$/)) {
S=RSTART
L=RLENGTH
ttys[parsepid($1)]=substr($1,S+4,L-5)
}
}
END {
for (pid in procs) {
tty=ttys[pid]
if (tty == "") tty = "N/A"
print pid,uids[pid],users[pid],tty,procs[pid]
}
}
'
fi | Passing "awk" as an argument uses the new, improved method. Compared to the older method this awk way doesn't spawn nearly as many sub processes to query the files inside /proc.
Finally. I have (somewhat) universal shell method to list processes? Right? _________________ ..: Zucca :..
My gentoo installs: | init=/sbin/openrc-init
-systemd -logind -elogind seatd |
Quote: | I am NaN! I am a man! |
|
|
Back to top |
|
|
geki Advocate
Joined: 13 May 2004 Posts: 2387 Location: Germania
|
Posted: Thu Jul 20, 2023 8:22 pm Post subject: |
|
|
You can set for all columns but the args column a header-name. The length of the header-name is the width of the column. With that knowledge you can split the line to the respective entries. If you find a comma in the tty entry, you can map the major number to /dev/<device> like /dev/tty or /dev/pts by Code: | $ busybox ps -Ao tty|grep -v "?"
...
136,0
136,0
136,0
$ grep "136 " /proc/devices
136 pts
$ ls /dev/pts/0
/dev/pts/0 | That is as far as it gets with pses for now. I would keep processing /proc to a minimum. But that's me.
edit P.S.: This is just a basic example. grep should match with start of line (^). But how you parse /proc/devices properly is up to you and the systems targeted. Same for the comma test of tty entry. There you should also verify that the rest of the entry is only numbers.
edit #2 Hah. Its not that easy to parse /proc/devices. An exercise for the reader. _________________ hear hear |
|
Back to top |
|
|
Zucca Moderator
Joined: 14 Jun 2007 Posts: 3686 Location: Rasi, Finland
|
Posted: Sat Jul 22, 2023 9:30 pm Post subject: |
|
|
Well. I tried playing around with the header name trick and ran: Code: | ps -Ao user="$(printf %32s)",tty="$(printf %32s)",args | busybox accepts spaces as header name while procps does not.
I'm starting to question why am I even doing this? :D I guess I like challenges.
Next solution would be to pipe the printf generated string to tr " " "-" or so... _________________ ..: Zucca :..
My gentoo installs: | init=/sbin/openrc-init
-systemd -logind -elogind seatd |
Quote: | I am NaN! I am a man! |
|
|
Back to top |
|
|
Zucca Moderator
Joined: 14 Jun 2007 Posts: 3686 Location: Rasi, Finland
|
Posted: Mon Sep 16, 2024 7:30 pm Post subject: |
|
|
So... oops? I made it into a small project.
https://codeberg.org/Zucca/procfsps
Available on my overlay too. _________________ ..: Zucca :..
My gentoo installs: | init=/sbin/openrc-init
-systemd -logind -elogind seatd |
Quote: | I am NaN! I am a man! |
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|