Responder a un aviso de SSH antes del primer comando con el rubí y Net :: SSH

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

  •  19-09-2019
  •  | 
  •  

Pregunta

Estoy intentando conectar, usando Net :: SSH, a un servidor que inmediatamente después de inicio de sesión ejecuta un script que requiere la colaboración de los usuarios. El usuario tiene que introducir "1" o "2" y recibirá algunos datos a través de en el terminal después.

Mi problema es que, aunque soy capaz de conectar, no puedo encontrar una manera de enviar "1 \ n" para el servidor y para recibir la salida.

El código siguiente se detiene en. "INFO - net.ssh.connection.session [80906b74]: channel_open_confirmation: 0 0 0 32 768"

Uso channel.exec ( "1 \ n") en lugar de channel.send_data como era de esperar no funciona bien.

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    

Cualquier idea, cualquier persona?

Gracias de antemano

¿Fue útil?

Solución

Se puede verificar que su llamada está sucediendo send_data después se muestra la solicitud desde el servidor remoto? Intenta construir un bloque channel.on_data alrededor de su llamada send_data para que pueda verificar que se muestra la solicitud prevista desde el servidor antes de enviar una respuesta.

Es posible que no quiere estar usando exec aquí. A partir de la documentación para Net :: SSH :: :: Conexión Canal:

  

envía una solicitud pidiendo que el canal   la orden dada invocarse.

Se está queriendo enviar una cadena de texto para responder a un aviso, no aplicar el comando. Los documentos muestran exec siendo utilizados para enviar comandos CLI completa como "ls -l / home".

En lugar de ello, send_data es probablemente lo que quiere. Los documentos muestran que utiliza para enviar un texto arbitrario como channel.send_data("the password\n"). Nótese, sin embargo, esta frase en la documentación:

  

Tenga en cuenta que no envía inmediatamente   los datos a través del canal, pero   en cambio simplemente añade los datos dados   a búfer de salida del canal,   preparatorio para ser empaquetado y   enviados la próxima vez que la conexión   está aceptando datos.

Es posible que desee echar un vistazo a channel.request_pty . Parece estar diseñado para la interacción con una aplicación basada en consola.

Si usted está tratando de escritura (en esencia) de una sesión SSH que normalmente hacer de forma manual, puede que le resulte más fácil de usar una interfaz expect similar (por ejemplo, una joya como sshExpect podría valer la pena probar).

Otros consejos

Gracias a todos por los punteros. He sido capaz de poner mi dedo en la llaga - además de usar channel.request_pty también era necesario solicitar una concha. A continuación, finalmente funciona como se espera:

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    

No estoy terriblemente familiar con las librerias de Net :: SSH así que no puedo ayudar con eso per se pero suena como que podría lograr lo que desea utilizar Capistrano .

Por ejemplo, tengo una tarea Capistrano, que se conecta a un servidor remoto, se ejecuta un comando que espera de entrada y luego continúa. Capistrano se encarga de la E / S remotas. Tal vez eso podría ser una solución para usted?

Espero que ayude!

Si ejecuto "1\n" en una cáscara de la respuesta que consigo es: bash: 1: command not found

Si ejecuto echo "1" me sale: 1

¿Está seguro que desea tratar de ejecutar el texto que va a enviar? Tal vez estabas buscando algo como:

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

No soy hábil con que lib, pero en SSH puede abrir múltiples canales. Puede que el servidor sólo responde al primer canal por defecto y si se abre otro que un nuevo shell.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top