SSH faz com que o loop pare

28

Eu finalmente consegui resumir um problema com o qual tenho lutado por algumas semanas. Eu uso o SSH com "chaves autorizadas" para executar comandos remotamente. Tudo está bem, exceto quando eu faço isso em um loop while. O loop termina após concluir qualquer iteração com um comando ssh.

Por um longo tempo eu pensei que isso fosse algum tipo de estranheza ksh, mas agora eu descobri que bash realmente se comporta de forma idêntica.

Um pequeno programa de amostra para reproduzir o problema. Isso é destilado de uma implementação maior que tira instantâneos e os replica entre os nós em um cluster.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(Note que há um caractere TAB na expressão de busca do grep conforme a definição do comportamento da opção zfs list "-H").

Meu exemplo tem alguns sistemas de arquivos ZFS para a raiz, onde todas as "zonas" têm seu sistema de arquivos raiz em um conjunto de dados com nome semelhante a

POOL / zones / app1zone
POOL / zones / group2 / app2zone

etc.

O loop acima deve criar um instantâneo para cada um dos conjuntos de dados selecionados, mas ao invés disso, ele opera somente no primeiro e depois sai.

O programa encontra o número certo de conjuntos de dados que podem ser facilmente confirmados, verificando o arquivo "/ tmp / actionlist" depois que o script existir.

Se o comando ssh for substituído, por exemplo, por um comando echo, o loop itera todas as linhas de entrada. Ou o meu favorito - adicione "eco" ao comando ofensivo.

Se eu usar um loop for no lugar, também funciona, mas devido ao tamanho potencial da lista de conjuntos de dados, isso pode causar problemas com o tamanho máximo da linha de comando expandida.

Agora tenho 99,999% de certeza de que apenas aqueles loops com comandos ssh neles me causam problemas!

Observe que a iteração na qual o comando ssh é executado é concluída. É como se os dados inseridos no loop while fossem subitamente perdidos ... Se as primeiras linhas de entrada não executarem um comando ssh, o loop continuará até que ele execute o comando SSH.

No meu laptop onde estou testando, eu tenho duas VMs do Solaris 10 com apenas dois ou três conjuntos de dados de amostra, mas o mesmo está acontecendo nos grandes sistemas SPARC em que isso deve entrar em operação e há muitos conjuntos de dados.

    
por Johan 26.02.2013 / 11:30

1 resposta

39

O SSH pode estar lendo a entrada padrão, consumindo sua lista de ações. Tente redirecionar a entrada padrão do ssh para / dev / null:

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

Como regra geral, ao executar comandos que podem interferir na entrada padrão em um loop de while read , gosto de envolver todo o corpo do loop em chaves:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done
    
por 26.02.2013 / 15:48