Isso soa como uma condição de corrida, e olhando para o seu script, eu acho que vejo onde.
Pelo que entendi, você tem um script que contém as duas linhas seguintes (entre outras):
ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts
E você inicia esse script várias vezes.
Esta sequência de eventos pode explicar o seu problema:
- Um dos scripts abre
~/.ssh/known_hosts
para pré-forma o comandossh-keygen -R
. Neste ponto, o comandossh-keygen
tem o arquivo inteiro lido na memória para que possa remover a linha de destino. - Outro script acabou de executar
ssh-keyscan
e de gravar a linha no arquivo. - O processo
ssh-keygen
do primeiro script (aquele do passo 1) começa a escrever o arquivo, mas como ele leu o arquivo antes da conclusão da etapa 2, o arquivo que está sendo escrito não contém a linha descrita 2 adicionado. Então a linha da etapa 2 é apagada. - O segundo script serve para executar o
ssh
, somente a chave do host não está emknown_hosts
devido ao problema mencionado na etapa nº 3. Então o ssh trava querendo que o usuário confirme a chave.
Mais detalhes:
Os programas em segundo plano não podem ler a partir do terminal, ao tentar fazer isso, os resultados nesse programa são enviados com um SIGTTIN. No entanto, no seu strace, ele mostra o programa recebendo um SIGTTOU. Normalmente, os programas em segundo plano podem gravar no terminal sem problemas, no entanto, o OpenSSH ativa explicitamente uma definição de terminal chamada tostop
, que resulta nesse comportamento. Indo ainda mais longe, o OpenSSH tem um manipulador de sinal no SIGTTOU (entre outros) que resulta no código OpenSSH entrando em um loop infinito até que você leve o processo para o forground (no ponto em que ele pode exibir o prompt e parar de ser sinalizado).
Como você quer resolver isso é outra questão.
- Uma solução seria adicionar bloqueio (há um utilitário
flock
que você pode usar) e bloquear o arquivoknown_hosts
antes dessas duas linhas e, em seguida, desbloquear depois que elas forem concluídas. - Outra solução seria adicionar a opção ssh
StrictHostKeyChecking=no
. Você já está derrotando a finalidade do arquivoknown_hosts
com essas duas linhas do script, então é melhor desativá-lo.