当前位置: 动力学知识库 > 问答 > 编程问答 >

How to output data from multiple sources for a list of hosts via SSH (using Bash)

问题描述:

Below is my current Bash code for going to a list of boxes from the file "testhost", it will go to each host listed in testhost and gather information for my wiki and print it out to a log file in Wiki format. I am trying to do a couple of things with this code below, for instance I would like to be able to cut back the number of times I have to SSH to a box, if I could set multiple variables at once that would be great.

Secondly I would like to set local variables on the SSH'd host, then run some if statements and return the value, I'm having a little trouble with that.

Any tips on how you would approach this would be great.

#!/bin/bash

for i in `cat testhost`

do

HOSTZ=`ssh $i "hostname" |cut -d. -f1`

printf "^ $HOSTZ ^^^^^^\n" >> WikiMike

echo "^ Make ^ Model ^ CPU ^ Number of Cores ^ Memory ^ Serial Number ^" >> WikiMike

MAKE=`ssh $i "dmesg" |grep ProL |awk 'NR==1' |awk '{print $2}'`

MODEL=`ssh $i "dmesg" |grep ProL |awk 'NR==1' |awk '{print $3,$4,$5}' |sed 's/[,]//g'`

CPUZ=`ssh $i "cat /proc/cpuinfo" |grep 'model name' |awk 'NR==1' |awk '{print $7,$8,$9}'`

COREZ=`ssh $i "cat /proc/cpuinfo" |grep processor |tail -n 1 |awk '{print $3}'`

COREZ=`expr $COREZ + 1`

MEMZ=`ssh $i "cat /proc/meminfo" |head -n 1 |awk '{print $2}'`

MEMZ=`expr $MEMZ / 1024 / 1024`

SERIAL=`ssh $i "lshal" |grep system.hardware.serial |awk '{print $3}' |tr -d "'"`

echo "| $MAKE | $MODEL | $CPUZ | $COREZ | $MEMZ gb | $SERIAL | " >> WikiMike

echo "^ Interface ^ Name ^ MAC ^ IP ^ Broadcast ^ Mask ^" >> WikiMike

ssh $i "/sbin/ifconfig" |egrep "eth|inet|bond" |sed 's/eth/~eth/g' |tr "\012" " " |tr "~" "\012" |grep inet |awk '{print "| | ",$1," | "$5," | ",$7," | ",$8," | ",$9," |"}' >> WikiMike

printf "\n\n" >> WikiMike

done

网友答案:

You can restructure your program like this to reduce necessary ssh connections to one per host:

#!/bin/bash

function wikiOutput() {
    HOSTZ=$( hostname | cut -d. -f1 )
    MAKE=$( dmesg | grep ProL | awk 'NR==1' | awk '{print $2}')
    MODEL=$( dmesg | grep ProL | awk 'NR==1' | awk '{print $3,$4,$5}' | sed 's/[,]//g')
    CPUZ=$( cat /proc/cpuinfo | grep 'model name' | awk 'NR==1' | awk '{print $7,$8,$9}')
    COREZ=$( cat /proc/cpuinfo | grep processor | tail -n 1 | awk '{print $3}')
    COREZ=$( expr $COREZ + 1)
    MEMZ=$( cat /proc/meminfo | head -n 1 | awk '{print $2}')
    MEMZ=$( expr $MEMZ / 1024 / 1024)
    SERIAL=$( lshal | grep system.hardware.serial | awk '{print $3}' | tr -d "'")
    INTERFACES=$( /sbin/ifconfig | egrep "eth|inet|bond" | sed 's/eth/~eth/g' | tr "\012" " " | tr "~" "\012" | grep inet | awk '{print "|             | ",$1,"  | "$5," | ",$7," | ",$8," | ",$9," |"}' )

    echo "^  $HOSTZ  ^^^^^^"
    echo "^  Make  ^  Model  ^  CPU  ^  Number of Cores  ^  Memory  ^  Serial Number  ^"
    echo "|  $MAKE  |  $MODEL  |  $CPUZ  |  $COREZ  |  $MEMZ gb  |  $SERIAL  | "
    echo "^  Interface  ^  Name       ^  MAC           ^  IP                ^  Broadcast              ^  Mask  ^"
    echo "$INTERFACES"
    echo ; echo
}

# for each host:
while read hostname
do
    # define function remotely, then call it:
    { type wikiOutput | tail -n +2 ; echo wikiOutput ; } | ssh "$hostname"
done < testhost >> WikiMike

Note that your current code does not always follow shell best practices, e.g.:

  • you should use $() instead of backticks
  • there are superfluous uses of cat
  • using expr can be replaced with arithmetic evaluation $(( )) which is both a built-in and more readable

I have not corrected most of these to prevent distracting from the actual problem.

分享给朋友:
您可能感兴趣的文章:
随机阅读: