November 17th, 2010 mysurface
You may already realized Linux happened to appear at many places, such as web server, storage server, desktop, kiosk machine, mobile devices. Yes, more and more devices running embedded Linux. Yeah, Android is a modified version of Linux kernel too!
Scarcity is still an issue, embedded Linux can be very different to Linux that hosted on desktop or high-end servers. You may be provided with simple shell (sh but not bash, not ksh and not csh) and limited commands, it bundles into a BusyBox, The Swiss Army Knife of Embedded Linux.
I am a bit upset when I holding this so called Swiss Army Knife ( probably a customized one, super tiny one), why this command also don’t have, that command also not available. Well, I am still quite new to embedded Linux perhaps.
My busybox does not have bash, therefore a lots of bash syntax can’t be applied to my script, ouch! I do wrote some post about bash. Such as if … then … fi and download multiple files from a site using for loop like c in bash. The if…then…fi examples may still valid for shell script, because that is the fundamental one.
The very basic for loop for shell script is like this
for p in 1 2 3 4 5
do
echo $p
done
You can do simplified it by using command seq ( if seq is available in your busybox)
for p in `seq 1 5`
do
echo $p
done
Well, my swiss army knife doesn’t contain me seq command, it doesn’t have bash, no top command, giving me a fake ps with limited info. I can’t check my how busy is my processors and thread easily (because fake ps do not tells you that), I need to access it through /proc/[PID] and thank God, it does provide me the cut command.
Yes I able to cut by using my swiss army knife.
Due to the scarcity, I learn more about /proc. /proc is a pseudo-filesystem that provides tones of process information. Check out the proc 5 manual for detail information.
man 5 proc
What I am interested is the file /proc/[PID]/stat, the status information about the process. stat provides a long array of values, I am interested on column 1,2,14 and 15 which is PID, Command, utime and stime.
Ok, list me all the process’s utime and stime. I wrote a simple script call probe.sh.
#!/bin/sh
for p in /proc/[0-9]*;
do
cat $p/stat | cut -d" " -f1,2,14,15
done
The output looks decent, time takes less then 1 second.
...
6 (cpuset) 0 0
608 (scsi_eh_0) 0 1
612 (scsi_eh_1) 0 0
615 (scsi_eh_2) 0 1
661 (kpsmoused) 0 0
671 (kstriped) 0 0
677 (kondemand/0) 0 0
7 (khelper) 0 8
707 (usbhid_resumer) 0 0
854 (udevd) 0 11
real 0m0.965s
user 0m0.138s
sys 0m0.752s
But the list is long and overwhelming. What if I have targeted pid range?
#!/bin/sh
START=2000
END=3000
until [ $START -gt $END ]
do
p="/proc/$START/stat"
if [ -f $p ] ;
then
cat $p | cut -d" " -f1,2,14,15
fi
START=`expr $START + 1`
done
The output is promising, but it took too long to produce that.
2391 (syslog-ng) 0 0
2392 (syslog-ng) 1 11
2451 (gpm) 0 0
2882 (dhcpcd) 0 0
real 0m7.145s
user 0m0.959s
sys 0m5.640s
The expr for arithmetic function seems to consume a lots of processing time.
Another approach, which amazingly gives correct result and fast.
START=2000
END=3000
for p in /proc/[0-9]*;
do
pid=`basename $p`
# omg no basename? replace with the line below
# pid=`cat $p | cut -d"/" -f3`
if [ $pid -ge $START ]
then
if [ $pid -le $END ]
then
cat $p/stat | cut -d" " -f1,2,14,15
fi
fi
done
Check out the result. Outstanding isn’t it?
2391 (syslog-ng) 0 0
2392 (syslog-ng) 1 11
2451 (gpm) 0 0
2882 (dhcpcd) 0 0
real 0m0.550s
user 0m0.069s
sys 0m0.447s
I had briefly illustrate the looping mechanism on shell script, I hope that gives you some ideas while you working under embedded Linux.
Posted in cut, for, if, seq, Text Manipulation | Hits: 251170 | 19 Comments »