Como executar vários comandos ssh paralelos e armazenar saídas em variáveis

3

Eu tentei escrever um script de shell que loga em vários hosts via ssh , executa alguns comandos e imprime o resumo da execução. Até agora, escrevi um script que funciona de maneira sequencial . Mas é lento, quero reescrevê-lo de forma paralela. Eu sei que posso usar & para executar vários comandos ssh paralelos e usar "substituição de comando" para armazenar subshell output em variável. Mas não posso combiná-los corretamente.

Até agora, eu saí esse código. Mas ainda funciona de forma sequencial.

#!/bin/bash

hosts=('host-1' 'host-2' 'host-3')

cmd='sleep $[ (( $RANDOM % 20 ) + 1) /10 ]s && echo hello world'
i=0
for host in ${hosts[@]}; do
    var1=$(ssh $host $cmd &)
    echo "i = $i"
    outputs[i]="$var1"
    ((i++))
done

echo 'wait'
wait

echo ${outputs[@]
    
por gzc 17.06.2017 / 12:10

1 resposta

1

Eu não acho que você pode usar utilmente atribuições de variáveis em segundo plano (com substituição de comandos ou não), já que as tarefas em segundo plano são executadas em uma sub-camada. por exemplo,

foo=x
foo=$(echo y) &
echo "$foo"

imprimirá x , já que a segunda atribuição só se aplica à sub-camada.

Por outro lado, baseando-se no interior da substituição do comando não faz o que você quer, o shell aguarda o comando de qualquer maneira, e você obtém as tarefas executadas sequencialmente:

sleepecho() { sleep "$1"; echo "$2"; }
foo=$( sleepecho 5 abc & )      # returns after five seconds
echo "$foo"                     # prints 'abc'

O que você poderia fazer seria armazenar a saída dos comandos em arquivos temporários. Isso permitiria que o backgrounding funcionasse, e também poderia ser melhor se a saída fosse muito longa.

dir=$(mktemp -d)
for h in "${hosts[@]}" ; do
    ssh "$h" "$cmd" > "$dir/$h" & 
done
wait
do something with "$dir/"*

Embora existam várias soluções prontas para executar comandos em vários hosts via ssh ...

    
por 17.06.2017 / 12:21

Tags