musasabi musasabi - 4 months ago 32
Linux Question

More efficient script?

I just threw together a quartet of Raspberry Pi 3's as a dedicated BOINC cluster. I like what I've got, but monitoring progress is a little meh since my main desktop environment is Linux (Windows has good GUI's with remote monitoring support, but the Linux equivalents appear to be defunct).

Anyway, I threw together this bash script to keep track of things


tasks=($(boinccmd --get_tasks | grep ')' | cut -d ')' -f1))
progress=($(boinccmd --get_tasks | grep fraction | awk '{ print $NF }'))
remaining=($(boinccmd --get_tasks | grep remaining | awk '{ print $NF }'))

tabs -4 &> /dev/null

echo "${tasks[-1]} task(s)"

for i in "${tasks[@]}"; do
if [ $(echo "${progress[((--i))]} > 0.000" | bc) -eq 1 ]; then
progress_as_percent=$(echo "scale=1; (${progress[((--i))]}*100)/1" | /usr/bin/bc)
remaining_as_hours=$(echo "scale=0; ${remaining[((--i))]}/3600" | /usr/bin/bc)
remaining_as_minutes=$(echo "scale=0; (${remaining[((--i))]}/60)-(${remaining_as_hours}*60)" | /usr/bin/bc)
echo -e "#$i"'\t'"${progress_as_percent}%"'\t'"${remaining_as_hours}:${remaining_as_minutes}"

cpu_temp="$(sudo cat /sys/class/thermal/thermal_zone0/temp)"
cpu_temp=$(echo "scale=1; ${cpu_temp}/1000" | bc)

core0freq="$(sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq)"
core0freq=$(echo "scale=2; ${core0freq}/1000000" | bc)
core1freq="$(sudo cat /sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq)"
core1freq=$(echo "scale=2; ${core1freq}/1000000" | bc)
core2freq="$(sudo cat /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq)"
core2freq=$(echo "scale=2; ${core2freq}/1000000" | bc)
core3freq="$(sudo cat /sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq)"
core3freq=$(echo "scale=2; ${core3freq}/1000000" | bc)

tabs -8 &> /dev/null

echo "${core0freq}/${core1freq}/${core2freq}/${core3freq}GHz ${cpu_temp}'C"

And the output looks about like this:

12 task(s)
#1 33.3% 11:14
#3 29.2% 12:50
#6 31.4% 12:15
#10 31.6% 11:58

1.20/1.20/1.20/1.20GHz 46.6'C

I have no idea the efficiency of
vs other alternatives, nor the many shells I'm sure this script instantiates. Obviously, since the RPi3 is such an underpowered machine when it comes to FLOPS per dollar, this build isn't principally concerned with efficiency... but none the less! I want to know what I could do to lean up getting the information I'm after. Keeping track of the workload isn't really all that important, but the CPU temperatures and core clocks are.

Thanks in advance. =)

EDIT: per request, here's what
boinccmd --get_tasks
looks like:

pi@serverpi:~ $ boinccmd --get_tasks

======== Tasks ========
1) -----------
name: p2030.20151124.G196.37-01.56.N.b3s0g0.00000_1563_1
WU name: p2030.20151124.G196.37-01.56.N.b3s0g0.00000_1563
project URL:
report deadline: Sat Sep 17 01:19:42 2016
ready to report: no
got server ack: no
final CPU time: 28977.680000
state: downloaded
scheduler state: preempted
exit_status: 0
signal: 0
suspended via GUI: no
active_task_state: UNINITIALIZED
app version num: 142
checkpoint CPU time: 28917.330000
current CPU time: 28977.680000
fraction done: 0.502852
swap size: 127 MB
working set size: 125 MB
estimated CPU time remaining: 28691.772814

And on for (in my case) 14 separate work units.


You seem to invoke boinccmd three times at the start and then invoke bc three times for each task. So, for 14 tasks, you would have 45 processes, whereas you could just invoke boinccmd once and awk once and get much the same.

I don't have forever to do it all for you, but it could look as simple as this:

boinccmd --get_tasks | awk -F '[):]' '
   /^[0-9])/   {tasks++}
   /fraction/  {pctdone=$2*100}
   /remaining/ {hrs=int($2/3600)
                printf "#%d\t%2.1f\t%d:%02d\n",tasks,pctdone,hrs,mins}
   END{printf "%d task(s)\n",tasks}


#1  50.3    7:58
#2  98.0    1:00
2 task(s)