0

I have a script to get server health from multiple servers like this:

#!/bin/bash
for ip
do
    ssh 192.168.1.209 ssh root@$ip cat /proc/loadavg | awk '{print $1}' #CPU Usage
    free | grep Mem | awk '{print $3/$2 * 100.0}' #Memory Usage
    df -khP  | awk '{print $3 "/" $2}' | awk 'FNR == 2' #Disk Space
    df -kihP  | awk '{print $3 "/" $2}' | awk 'FNR == 2' #Inode Space
    date +'%d %b %Y %r %Z' #Datetime
    ps -eo user,pid,pcpu,pmem,args|sort -nr -k3|head -5 #Process
done

The 209 is acting like a portal on my network so I have to ssh to it 1st in order to access other servers. By typing this command on terminal:

./my_script.sh 192.168.1.210 192.168.1.211 192.168.1.212

I would like to get each of the command output (ps,date etc) from each server. Expected output for 2 servers should be like:

0.11 #health from server 1
4.82577
1.7G/49G
46K/49M
27 Dec 2016 05:34:57 PM HKT
root        93  0.0  0.0 [kauditd]
root         9  0.0  0.0 [rcuob/0]
root      8740  0.0  0.0 ifstat --scan=100
root       829  0.0  0.0 /usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
0.00  #health from server 2
4.82422
1.7G/49G
46K/49M
27 Dec 2016 05:34:57 PM HKT
root        93  0.0  0.0 [kauditd]
root         9  0.0  0.0 [rcuob/0]
root      8740  0.0  0.0 ifstat --scan=100
root       829  0.0  0.0 /usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid

The problem that I'm facing is that It seems like it's only getting the health info from one server only. Why is that? Is it because I cannot do SSH like this? I'm using PHP exec() function to execute the script btw, to further format and display it on my local page.

2
  • oh i forgot to mention, the 209 is acting like a portal on my network. I can only ssh to 210,211 etc from 209. so Im actually ssh to 209 first Commented Dec 27, 2016 at 9:57
  • how do I do that? I have already given all of my code Commented Dec 27, 2016 at 10:05

2 Answers 2

1

The best way to do that in bash is to use Here Documents << and run a loop over each of the arguments ($@) passed to the script as

for ip in "$@"
do
    ssh 192.168.1.209 ssh root@"$ip" <<-EOF
    cat /proc/loadavg | awk '{print $1}'
    free | grep Mem | awk '{print $3/$2 * 100.0}' 
    df -khP  | awk '{print $3 "/" $2}' | awk 'FNR == 2'
    df -kihP  | awk '{print $3 "/" $2}' | awk 'FNR == 2'
    date +'%d %b %Y %r %Z'
    ps -eo user,pid,pcpu,pmem,args|sort -nr -k3|head -5
    EOF
done

Remember to NOT have leading or trailing whitespaces before header <<-EOF and the final EOF, use tab-space for the terminating EOF.

You can run the script now as

./my_script.sh 192.168.1.210 192.168.1.211 192.168.1.212     

Also you can wrap the contents of the script in a simple bash script and run it in one shot as

#!/bin/bash

cat /proc/loadavg | awk '{print $1}'
free | grep Mem | awk '{print $3/$2 * 100.0}' 
df -khP  | awk '{print $3 "/" $2}' | awk 'FNR == 2'
df -kihP  | awk '{print $3 "/" $2}' | awk 'FNR == 2'
date +'%d %b %Y %r %Z'
ps -eo user,pid,pcpu,pmem,args|sort -nr -k3|head -5

Call the above script as commandlist.sh and call it inside the for-loop as

ssh 192.168.1.209 ssh root@"$ip" 'bash -s ' < /path-to/commandlist.sh
Sign up to request clarification or add additional context in comments.

6 Comments

I am getting ./health.sh: line 14: warning: here-document at line 4 delimited by end-of-file (wanted `EOF') ./health.sh: line 15: syntax error: unexpected end of file
It is still the same, btw "<<-EOF" should be "<< EOF"?
@LimSY: Also for the terminating token EOF before done, do not use <space> character, use <tab> and can you try once?
Now it does not have any error, but without any output though. i have to press ctrl+c to cancel
@LimSY: Can you try the last suggestion from my answer? with the commands in a single file
|
0

Well, I’d do something completely different.

First I’d write a commandlist.sh script as follows (not forgetting to make it executable...):

#!/bin/bash
echo "# Health from $(hostname)"
cat /proc/loadavg | cut -d' ' -f1 #CPU Usage
free | grep Mem | awk '{print $3/$2 * 100.0}' #Memory Usage
df -khP  | awk 'FNR == 2 {print $3 "/" $2}' #Disk Space
df -kihP  | awk 'FNR == 2 {print $3 "/" $2}' #Inode Space
date +'%d %b %Y %r %Z' #Datetime
ps -eo user,pid,pcpu,pmem,args|sort -nr -k3|head -5 #Process

(mmh.. I would produce the same output with very different code, but since it’s your script I’ve only edited out a couple of superfluous awk invocations.)

Then, I’d place it on the 209, where I’d also install GNU parallel. Separately, I’d write the file ~/.parallel/sshloginfile as follows:

1/192.168.1.210
1/192.168.1.211
1/192.168.1.212

and I’d run the command

ssh 192.168.0.209 parallel -S .. --nonall --bf commandlist.sh ./commandlist.sh

Have a good look at man parallel for more possibilities.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.