Reagieren auf eine SSH-Eingabeaufforderung vor dem ersten Befehl mit Ruby und Net :: SSH

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

  •  19-09-2019
  •  | 
  •  

Frage

Ich versuche zu verbinden, mit Net :: SSH, auf einen Server, der unmittelbar nach Login führt ein Skript, das eine Eingabe von Benutzer erfordert. Der Benutzer hat „1“ oder „2“ eingeben und werden einige Daten über im Terminal danach erhalten.

Mein Problem ist, dass, obwohl ich in der Lage bin zu verbinden, ich kann nicht einen Weg finden, um auf „1 \ n“ an den Server zu senden und die Ausgabe zu erhalten.

Der folgende Code hält an. "INFO - net.ssh.connection.session [80906b74]: channel_open_confirmation: 0 0 0 32768"

Mit channel.exec ( "1 \ n") statt channel.send_data unsurprisingly funktioniert auch nicht.

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    

Alle Ideen, anyone?

Vielen Dank im Voraus

War es hilfreich?

Lösung

Können Sie überprüfen, ob Ihr send_data Anruf geschieht nach Sie die Eingabeaufforderung von dem Remote-Server zu bekommen? Versuchen Sie, einen channel.on_data Block um den send_data Anruf konstruieren, so dass Sie überprüfen können, dass Sie die erwartete Aufforderung vom Server erhalten, bevor Sie eine Antwort senden.

Sie möchten vielleicht nicht hier mit exec sein. Aus der Dokumentation für Net :: SSH :: Connection :: Channel:

  

Sendet eine Kanalanforderung fordern, dass   der gegebene Befehl aufgerufen werden.

Sie wollen eine Textzeichenfolge zu senden, um eine Eingabeaufforderung zu antworten, nicht einen Befehl aufzurufen. Die Dokumente zeigen werden exec zum Senden vollständigen CLI-Befehle wie "ls -l / home".

Stattdessen send_data ist wahrscheinlich das, was Sie wollen. Die Dokumente zeigen, es verwendet, um beliebigen Text wie channel.send_data("the password\n") zu senden. Beachten Sie jedoch, dieser Satz in der Dokumentation:

  

Beachten Sie, dass es nicht sofort senden   die Daten über den Kanal, aber   stattdessen lediglich anhängt die angegebenen Daten   an den Ausgangspuffer des Kanals,   Vorbereitung auf das Verpacken und   schickte das nächste Mal aus der Verbindung   akzeptiert Daten.

Sie können einen Blick auf channel.request_pty . Es scheint, mit einer Konsole-basierte Anwendung für die Interaktion ausgelegt werden.

Wenn Sie versuchen, auf (im Wesentlichen) Skript eine SSH-Sitzung, die Sie normalerweise manuell tun würde, können Sie es einfacher finden, eine expect-ähnliche Oberfläche zu verwenden (zum Beispiel ein Juwel wie sshExpect könnte ein Versuch) wert sein.

Andere Tipps

Vielen Dank für den Zeiger. Ich konnte meinen Finger auf dem Problem stellen - neben der Verwendung channel.request_pty war es auch notwendig, eine Schale zu beantragen. Die folgende schließlich funktioniert wie erwartet:

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    

Ich bin nicht sehr vertraut mit dem Net :: SSH Libs so kann ich nicht mit, dass per se helfen, aber es klingt wie Sie erreichen können, was Sie wollen mit Capistrano .

Zum Beispiel habe ich eine Capistrano Aufgabe haben, die auf einem Remote-Server verbindet, führt einen Befehl die Eingabe erwartet und geht dann weiter. Capistrano kümmert sich um die Remote-I / O. Vielleicht eine Lösung für Sie, dass könnte?

Hoffe, es hilft!

Wenn ich "1\n" in einer Shell ausführen die Antwort, die ich bekommen ist: bash: 1: command not found

Wenn ich echo "1" ausführen erhalte ich: 1

Sind Sie sicher, dass Sie versuchen, den Text Sie senden auszuführen? Vielleicht wie Sie waren auf der Suche nach etwas:

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

Ich bin mit dieser lib nicht beherrschen, sondern auf SSH können Sie mehrere Kanäle öffnen. Vielleicht nur der Server antwortet auf den ersten Standardkanal und wenn Sie ein anderes öffnen erhalten Sie eine frische Schale.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top