0

I have a few raspberry pi's creating reverse ssh tunnels on an ssh server. From that server I can connect on all the raspberry pi's. I want to create a bash script that will run on this ssh server, collect some information from all the raspberry pi's and generate an html report. I have something working already, it only connects on a single raspberry pi. I need to somehow loop it, so that it will connect on all the raspberry pi's.

The variable that must be looped somehow is $port because each raspberry pi connects on a unique port on the ssh server, and its from that port that the server can connect back on the raspberry pi's.

I'm guessing it will have to be something like... for each $port in ports.txt perform the following commands and put the results in the html table

#!/bin/bash

cpu="$(ssh -o StrictHostKeyChecking=no $user@localhost -p $port echo $[100-$(vmstat|tail -1|awk '{print $15}')]"%")"
dsk="$(ssh -o StrictHostKeyChecking=no $user@localhost -p $port df -h /dev/mmcblk0p2 | awk 'NR>1{print $5}')"
mem="$(ssh -o StrictHostKeyChecking=no $user@localhost -p $port free | grep -e-/+ | awk '{print $3/($3+$4) * 100.0 ''}' | cut -d '.' -f1)"
tmp="$(ssh -o StrictHostKeyChecking=no $user@localhost -p $port /opt/vc/bin/vcgencmd measure_temp | sed -e 's/temp=//')"
mda="$(ssh -o StrictHostKeyChecking=no $user@localhost -p $port /bin/ls -R -l /$user/media | /usr/bin/wc -l)"

echo '<html>'
echo '<head>'
echo '<title>BeatBox Report</title>'
echo '</head>'
echo '<body>'
echo '<table border="1" align="center">'
echo     '<tr>'
echo         '<td></td>'
echo         '<td>CPU Usage</td>'
echo         '<td>Disk Usage</td>'
echo         '<td>Memory Usage</td>'
echo         '<td>Temperature</td>'
echo         '<td>Media Count</td>'
echo     '</tr>'
echo     '<tr>'
echo         '<td>Client001</td>'
echo         "<td align="center">$cpu</td>"
echo         "<td align="center">$dsk</td>"
echo         "<td align="center">$mem%</td>"
echo         "<td align="center">$tmp</td>"
echo         "<td align="center">$mda</td>"
echo     '</tr>'
echo     '<tr>'
echo         '<td>Client002</td>'
echo         "<td align="center">$cpu</td>"
echo         "<td align="center">$dsk</td>"
echo         "<td align="center">$mem%</td>"
echo         "<td align="center">$tmp</td>"
echo         "<td align="center">$mda</td>"
echo     '</tr>'
echo     '<tr>'
echo         '<td>Client003</td>'
echo         "<td align="center">$cpu</td>"
echo         "<td align="center">$dsk</td>"
echo         "<td align="center">$mem%</td>"
echo         "<td align="center">$tmp</td>"
echo         "<td align="center">$mda</td>"
echo     '</tr>'
echo     '</table>'
echo '</body>'
echo '</html>'
2
0

I suggest to refactor your existing code into a function (get_stats) and call this function from a while loop which reads each port number from your port file (assuming one number per line):

#!/bin/bash

function get_stats {
    local port=$1

    local cpu="..."
    local dsk="..."
    # ... remaining assignments ...

    # Output an HTML table row for this client
    echo     '<tr>'
    echo         "<td>Client on port $port</td>"
    echo         "<td align='center'>$cpu</td>"
    # ... echo remaining vars in similar fashion ...
    echo     '</tr>'
}

# Print HTML intro
echo '<html>'
# ... more html code until end of table header ...
echo         '<td>Media Count</td>'
echo     '</tr>'

# Print statistics for each client in turn - one table row per client
portfile='ports.txt'
while read port; do
    get_stats $port
done <$portfile

# Print HTML outro
echo     '</table>'
echo '</body>'
echo '</html>'
10
  • I tried it like this, but the results are all the same. Like, it only connects to the first port in ports.txt and fills the information for all clients. paste.ofcode.org/fP4giceZv6mQPyvx5U8gnA
    – aristosv
    Apr 6 '16 at 18:55
  • @aristosv That's because you printed the entire HTML page in each call of get_stats. See my updated example: first, print the HTML header and table beginning outside the loop. Then, only print a single <tr> table row each time get_statsis called. Finally (outside the loop again), close the table and print the remaining HTML.
    – Guido
    Apr 6 '16 at 19:17
  • I have 3 ports in ports.txt but I only get one row in the html report. What did I do wrong? paste.ofcode.org/i4d4PsKyhHgQAKbjXkEnhw
    – aristosv
    Apr 7 '16 at 4:53
  • @aristosv If I take your script and replace all 5 ssh calls by local cpu=$(echo testcpu) etc. for debugging, I get 3 HTML rows as expected. See paste.ofcode.org/jYEbsQwknnvfm7FUK9c3Aq . It therefore seems to me that there is some problem with at least one of the ssh calls. I suggest to focus on each one in turn (starting with cpu) and comment the other local assignments out to see if one of them causes an error.
    – Guido
    Apr 7 '16 at 8:47
  • Your code works. But as soon as I define any one of the ssh calls it only shows 1 client. I tried them all one by one. Then all of them. Same result. As soon as I commented them all out, it showed more than one again.
    – aristosv
    Apr 7 '16 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.