Responder a un aviso de SSH antes del primer comando con el rubí y Net :: SSH
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
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.