3 ms·
This is running in a barebones Ubuntu container on my MacBook as BSDs don't use /proc: root@74c03a282fbe:/# ed a ls /proc/[0-9]/status | xargs -n 1 cat |
by williamcotton 3y ago
This is running in a barebones Ubuntu container on my MacBook as BSDs don't use /proc:
root@74c03a282fbe:/# ed
a
ls /proc/[0-9]/status | xargs -n 1 cat | awk '/^Name:/ { name = $2 } /^Pid:/ { pid = $2 } END { print "cmd: " name ", pid: " pid }'
.
w prc.sh
132
q
root@74c03a282fbe:/# chmod +x ./prc.sh
root@74c03a282fbe:/# hyperfine --warmup=100 "./prc.sh"
Benchmark 1: ./prc.sh
Time (mean ± σ): 2.2 ms ± 0.3 ms [User: 1.3 ms, System: 2.7 ms]
Range (min … max): 1.8 ms … 5.0 ms 880 runs
Warning: Command took less than 5 ms to complete. Results might be inaccurate.
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
- aunderscored 3y agoI think you may have convinced me to learn more awk with this. I'd have constructed something horrible with sed or so to do this. And this is just much cleaner
- williamcotton 3y agoThe AWK Programming Language, Second Edition was just released. I'd say it's an instant classic! CSV support is slowly rolling out... you can compile Kernighan's nawk from source right now, gawk has it in trunk I think, and GoAwk has had support and is now also following the --csv design decision made by Mr. Kernighan.
- mzs 3y agoI like your style, but it's not quite right: $ echo /proc/[0-9]/status | wc 1 7 105 $ echo /proc/[1-9]*/status | wc 1 483 8778 It also will sporadically print error messages due to all the race conditions. Here's my stab at it: $ cat dumbps #!/bin/sh case $# in 1) ;; *) echo "Usage: dumbps user" >&2 exit 2 ;; esac 2>&- find /proc -mindepth 2 -maxdepth 2 -type f -name status -user "$1" | awk '{ while ((getline li < $0) > 0) { if (li ~ /^Name:/) { split($0, fn, "/") print fn[3], substr(li, 6) break } } close($0) }' $ ./dumbps "$USER" | grep -w 'bash$' 1616678 bash $ ./dumbps 0 | grep -w 'systemd$' 1 systemd $ It's pretty fast too: $ ls -ld /proc/[1-9]*/status | awk '$3 == "root"' | wc 445 4005 29367 $ time ./dumbps >/dev/null Usage: dumdps user real 0m0.001s user 0m0.000s sys 0m0.001s $
- TristanBall 3y agoYou seem to have very similar races here though? Perfectly possible, even likely, for a process to end between "find" finding it and awk opening it... especially given the pipe buffer between the two. Personly I'd rather an "expect errors" approach.. break it out so that you can easily treat a failed open as a "continue next" scenario and hide just those errors
- mzs 3y ago2>&- hides races in find itself while ((getline li < $0) > 0) hides races in awk in practice Name: is the first line so cmd is not truncated Of course I got my test wrong though :D $ time ./dumbps 0 >/dev/null real 0m0.030s user 0m0.012s sys 0m0.022s