Responder a uma solicitação SSH antes do primeiro comando com rubi e Net :: SSH

StackOverflow https://stackoverflow.com/questions/2223194

  •  19-09-2019
  •  | 
  •  

Pergunta

Eu estou tentando se conectar, usando Net :: SSH, para um servidor que imediatamente após de login executa um script que requer entrada do usuário. O usuário tem que digitar "1" ou "2" e receberá alguns dados via no terminal depois.

Meu problema é que, embora eu seja capaz de se conectar, eu não consigo descobrir uma maneira de enviar "1 \ n" para o servidor e para receber a saída.

O código a seguir pára em "INFO - net.ssh.connection.session [80906b74]: channel_open_confirmation: 0 0 0 32768".

Usando channel.exec ( "1 \ n") em vez de channel.send_data sem surpresa não quer trabalhar.

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"], :verbose => :debug) do |session|

  session.open_channel do |channel|

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.send_data( "1\n")

  end

  session.loop
end    

Todas as ideias, qualquer um?

Agradecemos antecipadamente

Foi útil?

Solução

Você pode verificar se a sua chamada send_data está acontecendo após você receber o prompt do servidor remoto? Tentar construir um bloco channel.on_data em torno de sua chamada send_data para que você possa verificar se você obter o prompt de espera do servidor antes de enviar uma resposta.

Você não pode querer estar usando exec aqui. De docs para Net :: SSH :: Conexão :: Canal:

Envia um pedido de canal pedindo que o comando dado ser invocado.

Você está querendo enviar uma seqüência de texto para responder a uma solicitação, não invocar um comando. Os documentos mostram exec sendo usado para enviar comandos completa CLI como "ls -l / home".

Em vez disso, send_data é provavelmente o que você quer. Os documentos mostram que costumava enviar mensagens de texto arbitrária como channel.send_data("the password\n"). Note, no entanto, esta frase nos docs:

Note que ele não envia imediatamente os dados através do canal, mas em vez disso simplesmente anexa os dados fornecidos ao tampão de saída do canal, preparatório para ser empacotado e enviado da próxima vez que a conexão está a aceitar os dados.

Você pode querer dar uma olhada em channel.request_pty . Parece ser projetado para a interação com um aplicativo baseado em console.

Se você está tentando (em essência) script de uma sessão SSH que você faria normalmente manualmente, você pode achar que é mais fácil de usar um expect-como interface (por exemplo, uma jóia como sshExpect pode valer a pena tentar).

Outras dicas

Obrigado a todos para os ponteiros. Eu tenho sido capaz de colocar o dedo sobre o problema - além de usar channel.request_pty também foi necessário para solicitar uma concha. A seguir, finalmente funciona como esperado:

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"]) do |session|

  session.open_channel do |channel|

    channel.request_pty do |ch, success| 
      raise "Error requesting pty" unless success 

      ch.send_channel_request("shell") do |ch, success| 
        raise "Error opening shell" unless success  
      end  
    end

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.on_extended_data do |ch, type, data|
      STDOUT.print "Error: #{data}\n"
    end

    channel.send_data( "1\n" )

    session.loop
  end  
end    

Eu não sou terrivelmente familiarizados com as libs Net :: SSH para que eu não posso ajudar com isso por si só, mas parece que você poderia conseguir o que deseja usando Capistrano .

Por exemplo, eu tenho uma tarefa capistrano que se conecta a um servidor remoto, executa um comando que espera de entrada e, em seguida, continua. Capistrano cuida do remota i / o. Talvez isso poderia ser uma solução para você?

Espero que ajude!

Se eu executar "1\n" em um shell a resposta que recebo é: bash: 1: command not found

Se eu executar echo "1" eu recebo: 1

Você tem certeza que quer tentar executar o texto que você está enviando? Talvez você estava procurando algo como:

output = ""
Net::SSH.start('host', 'user', :password => "pass") do |ssh|
   output = ssh.exec! "echo 1"
end
puts output

Eu não sou proficiente com que lib, mas em SSH você pode abrir vários canais. Talvez o servidor só responde ao primeiro canal padrão e se você abrir um outro você começa um novo shell.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top