patternbashMinor
Extracting Linux configuration information using Bash and Perl
Viewed 0 times
perlusinglinuxextractingandconfigurationbashinformation
Problem
For few days I'm thinking about making my code faster and using less CPU. This code is a statusbar that runs in a loop. I'm asking because there's a lot of perl and I'm wondering if it could be done better.
date=$( date +"%F %R" )
battery=$(acpi -b | perl -n -e '/(\S+),\s+([0-9]+\%),\s(\S*)\s/ && print $1," ",$2," [ ",$3," ]"')
RAM=$(free -m | perl -n -e '/Mem\:\s*([0-9]+)\s*([0-9]+).*/ && print "RAM: (",$2," / ",$1,")MB"')
VolumeLv=$(amixer get Master -c 1 | perl -n -e '/\[(.*)\%\]/ && print $1')
backLightLv=$(xbacklight | perl -n -e '/^([0-9]*)/ && print $1')
statusBacklight=$?
backLightBar=""
VolumeBar=""
Sign=":"
NoSign="."
for i in $(seq 1 2 100)
do
if [ $i -gt $VolumeLv ]
then
VolumeBar=$(echo "$VolumeBar$NoSign")
else
VolumeBar=$(echo "$VolumeBar$Sign")
fi
if [ $statusBacklight -eq 0 ] && [ $i -gt $backLightLv ]
then
backLightBar=$(echo "$backLightBar$NoSign")
else
backLightBar=$(echo "$backLightBar$Sign")
fi
done
ETHcards=""
for interface in $(iwconfig 2> /dev/null | perl -n -e '/^([a-zA-Z0-9]*)\s.*ESSID\:.*$/ && print $1,"\n"')
do
IPANDMASK=$(ifconfig $interface | perl -n -e '/.*inet\ addr:([0-9\.]+).*Mask:([0-9\.]*)\s/ && print $1, "/", $2')
MAC=$(ifconfig $interface | perl -n -e '/HWaddr\s+([a-f0-9\:]+)\s*/ && print $1')
AP=$(iwconfig $interface 2>/dev/null | perl -n -e '/ESSID\:(\S*)/ && print $1')
MODE=$(iwconfig $interface 2>/dev/null | perl -n -e '/Mode:(\S+)\s/ && print $1')
ETHcards=$(echo "$ETHcards [ $interface ][ $MAC ][ $AP ][ $IPANDMASK ][ $MODE ] // ")
done
xsetroot -name "$date :: $battery;Volume: [$VolumeBar]$Mute $VolumeLv% BackLight: [$backLightBar] $backLightLv% // $RAM // $ETHcards"Solution
[...] there's a lot of perl and I'm wondering if it could be done better.
When you need to process the output of multiple commands,
as in your example
it's acceptable to call a
The part needs improvement the most is the loop over the network interfaces,
where you call
It would be better to rewrite this to call
At a glance, it seems to me that everything you do with Perl, you could also do with awk, which might be slightly lighter.
If performance is extremely important,
you could parse the output of all the commands with a single Perl or awk process, by carefully adding some marker lines in between commands, something like this:
This way the number of processes spawned will be drastically reduced,
and the performance difference will be noticeable.
When you need to process the output of multiple commands,
as in your example
acpi, free, amixer, xbacklight,it's acceptable to call a
perl for each.The part needs improvement the most is the loop over the network interfaces,
where you call
iwconfig $interface and ifconfig $interface repeatedly to extract different part of the output into different variables.It would be better to rewrite this to call
ifconfig and iwconfig just once per interface.At a glance, it seems to me that everything you do with Perl, you could also do with awk, which might be slightly lighter.
If performance is extremely important,
you could parse the output of all the commands with a single Perl or awk process, by carefully adding some marker lines in between commands, something like this:
marker='==== section ===='
{
acpi -b
echo $marker
free -m
echo $marker
amixer get Master -c 1
echo $marker
xbacklight
echo $marker
iwconfig
echo $marker
ifconfig
} | perl -ne '...'This way the number of processes spawned will be drastically reduced,
and the performance difference will be noticeable.
Code Snippets
marker='==== section ===='
{
acpi -b
echo $marker
free -m
echo $marker
amixer get Master -c 1
echo $marker
xbacklight
echo $marker
iwconfig
echo $marker
ifconfig
} | perl -ne '...'Context
StackExchange Code Review Q#138251, answer score: 4
Revisions (0)
No revisions yet.