Como definir o tempo limite para um comando ssh e também recuperar o resultado de comandos remotos

3

Eu tenho um script que é executado no bash, em um servidor RHEL que se conecta a milhares de nós e retorna com os valores de cerca de 5 comandos executados - Ele coleta informações apenas de servidores RHEL.

Funciona bem, mas o problema é que alguns nós acabam congelando quando eu executo os seguintes comandos:

rpm -q <package-name>
rpm --queryformat '%{installtime:date} %{name}\n' -q <package-name>

Agora, como isso interrompe positivamente meu script, desejo definir um tempo limite para o comando ssh e sair da sessão ssh se continuar aguardando a execução de um comando remoto por muito tempo [digamos 10 segundos]. Eu quero tempo limite e sair dessa sessão ssh e passar para o próximo nó quando isso acontece. Como faço isso?

Aqui está a parte do script em que eu atualmente pego as informações e as armazeno na variável chamada dump [Por favor, ignore meus scripts ruins, sou novo nisso]

dump=$(ssh -o ServerAliveCountMax=1 -o ServerAliveInterval=10 -o ConnectTimeout=10 -o BatchMode=yes $i "cat /proc/meminfo | grep -i \"memtotal\" | cut -d \":\" -f2 | tr -d \" \" | tr -d \"kB\"; cat /etc/redhat-release | cut -d \" \" -f7; dmidecode | grep -i \"prod\" | grep -vi \"desktop\"  | grep -iv \"id\" | cut -d \" \" -f3,4| tr \" \" \"_\" ; uptime | cut -d \" \" -f4,5 | tr \" \" \"_\" | tr -d \",\"; service kdump status 2>/dev/null | tr \" \" \"_\";");

Existe tempo para isso se continuar por muito tempo?

O QUE JÁ TENTEI:

(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > /dev/null) & pid=$!
(sleep 10 && kill -HUP $pid ) 2>/dev/null & watcher=$!
if wait $pid 2>/dev/null; then
    pkill -HUP -P $watcher
    wait $watcher
else
    echo -e "$i Unable to ssh" >> res && continue
fi

No entanto, desta forma, não estou conseguindo armazenar o resultado do comando rpm remoto.

Qualquer ajuda é extremamente apreciada.

    
por sidx4 28.03.2015 / 11:53

2 respostas

1

Use o GNU Parallel para paralelizar sua coleção:

parallel --slf rhel-nodes --tag --timeout 1000% --onall --retries 3 \
  "rpm -q {}; rpm --queryformat '%{installtime:date} %{name}\n' -q {}" \
  ::: bash bc perl

Coloque os nós em ~/.parallel/rhel-nodes .

--tag pré-anexará a saída com o nome do nó. --timeout 1000% diz que, se um comando demorar 10 vezes mais que a mediana a ser executada, ele será eliminado. --onall executará todos os comandos em todos os servidores. --retries 3 executará um comando até 3 vezes se falhar. ::: bash bc perl são os pacotes que você deseja testar. Se você tiver muitos pacotes, use a sintaxe cat packages | parallel ... em vez de parallel ... ::: packages .

O GNU Parallel é um paralelizador geral e facilita a execução de trabalhos em paralelo na mesma máquina ou em várias máquinas para as quais você tem acesso ssh.

Se você tem 32 tarefas diferentes que você quer rodar em 4 CPUs, uma forma direta de paralelizar é rodar 8 tarefas em cada processador:

O

GNUParallelgeraumnovoprocessoquandoumtermina-mantendoasCPUsativaseeconomizandotempo:

Instalação

Se o GNU Parallel não for empacotado para sua distribuição, você poderá fazer uma instalação pessoal, que não requer acesso root. Isso pode ser feito em 10 segundos ao fazer isso:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Para outras opções de instalação, consulte o link

Saiba mais

Veja mais exemplos: link

Assista aos vídeos de introdução: link

Percorra o tutorial: link

Inscreva-se na lista de e-mail para obter suporte: link

    
por 29.03.2015 / 12:11
1

Obrigado por suas tentativas de resolver isso.

Eu resolvi o problema agora, e a resolução necessária era tão simples, que me sinto um pouco idiota agora.

No código que eu usei anteriormente,

(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > /dev/null) & pid=$!

Tudo o que eu precisava fazer era redirecionar toda a saída para um arquivo na máquina local. É isso.

(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > **test**) & pid=$!

A única razão pela qual eu decidi postar uma resposta, foi porque a resposta que você deu exigiu que ferramentas externas / código fossem trazidos e usados, o que é algo que eu não quero fazer. Em vez disso, queria uma solução que pudesse ser aplicada sem depender da disponibilidade de pacotes ou da versão do sistema operacional.

Obrigado mesmo assim!

    
por 28.03.2015 / 15:44