Finalmente consegui resumir um problema com o qual estou lutando há 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 a conclusão de qualquer iteração com um comando ssh.
Por um longo tempo, pensei que isso fosse algum tipo de estranheza do ksh, mas agora descobri que o bash se comporta de maneira idêntica.
Um pequeno programa de amostra para reproduzir o problema. Isso é extraído 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
(Observe que há um caractere TAB na expressão grep search conforme a definição do comportamento da opção "-H" da lista zfs.)
Minha amostra possui alguns sistemas de arquivos ZFS para a raiz, onde todas as "zonas" têm seu sistema de arquivos raiz em um conjunto de dados chamado similar a
POOL / zonas / app1zone
POOL / zonas / group2 / app2zone
etc.
O loop acima deve criar um instantâneo para cada um dos conjuntos de dados selecionados, mas, em vez disso, opera apenas no primeiro e depois sai.
O fato de o programa encontrar o número certo de conjuntos de dados pode ser facilmente confirmado verificando o arquivo "/ tmp / actionlist" após a existência do script.
Se o comando ssh for substituído por, por exemplo, um comando echo, o loop percorrerá todas as linhas de entrada. Ou o meu favorito - acrescente "eco" ao comando incorreto.
Se eu usar um loop for em vez disso, ele também funcionará, mas devido ao tamanho potencial da lista de conjuntos de dados, isso pode causar problemas com o comprimento máximo da linha de comando expandida.
Agora tenho 99,999% de certeza de que apenas aqueles loops com comandos ssh me causam problemas!
Observe que a iteração na qual o comando ssh é executado é concluída! É como se os dados transmitidos para o loop while fossem repentinamente perdidos ... Se as primeiras linhas de entrada não executarem um comando ssh, o loop continuará até que realmente execute o comando SSH.
No meu laptop em que estou testando isso, tenho duas VMs 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 ser lançado, e há muitos conjuntos de dados.
fonte
actionlist
. Tente redirecionar a entrada padrão do ssh para/dev/null
Respostas:
O SSH pode estar lendo da entrada padrão, consumindo sua lista de ações. Tente redirecionar a entrada padrão do ssh para / dev / null:
Como regra geral, ao executar comandos que podem interferir na entrada padrão em um
while read
loop estilo, eu gosto de envolver todo o corpo do loop em chaves:fonte
( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )
difere da mesma maneira com o aparelho. Quero dizer, em termos de saída produzidos, e não sobre o fato de que a chave de fechamento deve estar em uma nova linha ...-n
opção de fazê-lo (efetivamente) reabrir seu stdin a partir de / dev / null.sudo
com o comando dentro do loop?