SSH for循环执行命令脚本

时间:2016-12-27 09:41:46

标签: php bash shell ssh scripting

我有一个脚本可以从多个服务器获取服务器健康状况,如下所示:

#!/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

209就像我网络上的门户网站一样,所以为了访问其他服务器,我必须首先使用它。在终端上输入以下命令:

./my_script.sh 192.168.1.210 192.168.1.211 192.168.1.212

我想从每个服务器获取每个命令输出(ps,date等)。 2台服务器的预期输出应该是:

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

我面临的问题是它似乎只从一台服务器获取健康信息。这是为什么?是因为我不能像这样做SSH吗?我正在使用PHP exec()函数执行脚本btw,以进一步格式化并在我的本地页面上显示它。

2 个答案:

答案 0 :(得分:1)

bash中执行此操作的最佳方法是使用Here Documents <<并对传递给脚本的每个参数($@)运行循环

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

请记住 NOT 在标题<<-EOF和最终EOF之前有前导空格或尾随空格,请使用制表符空格来终止EOF

您现在可以将脚本作为

运行
./my_script.sh 192.168.1.210 192.168.1.211 192.168.1.212     

此外,您可以将脚本的内容包装在一个简单的bash脚本中并一次性运行

#!/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

将上述脚本称为commandlist.sh,并将其作为

在for-loop中调用
ssh 192.168.1.209 ssh root@"$ip" 'bash -s ' < /path-to/commandlist.sh

答案 1 :(得分:0)

好吧,我会做一些完全不同的事情。

首先我写一个commandlist.sh脚本如下(不要忘记让它可执行......):

#!/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 ..我会使用非常不同的代码生成相同的输出,但由于它是您的脚本,我只编辑了几个多余的awk调用。)

然后,我将它放在209,我也将安装GNU parallel。 另外,我按如下方式编写文件~/.parallel/sshloginfile

1/192.168.1.210
1/192.168.1.211
1/192.168.1.212

我会运行命令

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

好好了解man parallel以获得更多可能性。