Loop através dos servidores e execute o comando

7

Eu tenho um conjunto de servidores mencionados em um arquivo de texto chamado network_list.txt . Como posso executar através dos servidores e executar o comando e exibir o resultado? Eu tentei o seguinte:

filename="network_list.txt"
service=httpd
while read -r line
do
    name="$line"
    ping -c 3 $name > /dev/null 2>&1;
    RETVAL=$?
        if [ $RETVAL -ne 0 ]
        then 
           echo "$name is down"
        else 
            echo "$name is up and running"
        fi
    http_status=$(ssh $name ps -ef | grep -v grep | grep $service | wc -l)
        if [ $http_status -ne 0 ]
        then
            echo "$service is up and running in $name"
        else
            echo "$service is down in $name"
        fi
done < "$filename"

Mas ele pára após o primeiro servidor.

Obrigado :).

    
por PistaBadamShake 05.12.2017 / 11:37

4 respostas

7

Você precisa redirecionar o comando stdin do SSH em seu loop para lugar nenhum, para evitar a leitura de todas as suas linhas. Isso deve ser feito:

http_status=$(ssh $name "ps -ef | grep -v grep | grep $service | wc -l" < /dev/null)
    
por 05.12.2017 / 12:10
8

Existe uma solução com os parâmetros -n -x :

http_status=$(ssh -nx name ps -ef | grep -v grep | grep $service | wc -l)

O -x desativa o encaminhamento do X11 para eliminar possíveis mensagens X11 forwarding request failed .

O -n redireciona o stdin de / dev / null (na verdade, impede a leitura do stdin).

    
por 05.12.2017 / 12:17
1

Embora a resposta aceita seja totalmente válida, gostaria de oferecer este script que pode ser útil caso alguém se depare com ele.

Uso

Então, obviamente, você precisaria mudar as linhas sob as linhas "Echo $ server $ serverIP" para refletir os comandos reais que você gostaria de usar. $ 1 é a primeira coisa que você digita depois de "./scriptname.sh" - por exemplo ./scriptname.sh $ 1 $ 2 $ 3 ... - e aqui está como isso se divide:

$ 1 deve ser o arquivo com seus nomes de host. $ 2 é o parâmetro posicional que você passa para a FunctionC (que sempre é chamada neste script de exemplo). $ 2 e $ 3 podem ser usados para chamar as outras Funções (A / B) - alternativamente você pode substituir $ 3 e $ 4 no EOF com "FunctionA" e "FunctionB" se você sempre quiser executá-los.

Espero que isso ajude alguém, que foi INVALUABLE para mim ao implantar pacotes ou testar coisas em todo o domínio.

#! /bin/bash
SVRList='ls ./$1'

#========[ FUNCTIONS ]===============

FunctionA () {
  for server in 'cat $SVRList | grep -v ^#'  # Makes variable "server" from each line in $SVRlist that is not commented
do
  serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
  echo "============= $server | $serverIP ============="
  #command that you'd like to run locally
done
}

FunctionB () {
      for server in 'cat $SVRList | grep -v ^#'
    do
      passedvar="192.16.${1}"
      serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
      echo "============= $server | $serverIP ============="
      ssh -q $serverIP '#command that you'd like to run remotely'
      ssh -q $serverIP '#second command, if you so fancy'
      ssh -q $serverIP "ping $passedvar"
      #^ is done just to show an example of what can be done
    done
    }

FunctionC () {
  for server in 'cat $SVRList | grep -v ^#'
do
  passedvar="192.16.${1}"
  serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
  echo "============= $server | $serverIP ============="
  ssh -q $serverIP "ping $passedvar"
  #^ is done just to show the power of positional parameters.
done
}

#========[ SCRIPT ]==========

if [ $# -lt 2 ] 
  then
  printf "Usage: %s <file containing list of server hostnames> <passed variable> <functions> \n" "$(basename "$0")" >&2
  exit 64
  else 
  echo "Starting Script"
fi

FunctionC $2
$3
$4
exit

Também OP:

Por que definir service = httpd? Pode ser melhor usar [testing e "service = $ 1", em que $ 1 pode ser httpd, splunkd ou qualquer outro serviço. Além disso, a variável http_status deve ser alterada para algo como "service_status" para tornar o script melhor documentado.

    
por 05.12.2017 / 17:16
1

Por que não usar pssh ?

link

É uma ferramenta SSH paralela que tem suporte para obter uma lista de hosts de um arquivo:

pssh -h network_list.txt ps -ef | grep -v grep | grep $service | wc -l

Depois, você pode analisar a saída como quiser

    
por 07.12.2017 / 15:51