0

Net :: SSHを使用して、ログイン直後にユーザーからの入力を必要とするスクリプトを実行するサーバーに接続しようとしています。ユーザーは「1」または「2」を入力する必要があり、その後、ターミナルでいくつかのデータを受信します。

私の問題は、接続はできても、サーバーに「1\n」を送信して出力を受信する方法がわからないことです。

次のコードは「INFO--net.ssh.connection.session[80906b74]:channel_open_confirmation:0 0032768」で停止します。

channel.send_dataの代わりにchannel.exec( "1 \ n")を使用しても、当然のことながら機能しません。

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    

何かアイデアはありますか?

前もって感謝します

4

5 に答える 5

2

リモートサーバーからプロンプトを受け取った後send_data、通話が行われていることを確認できますか?応答を送信する前にサーバーから期待されるプロンプトが表示されることを確認できるように、呼び出しの周囲にブロックを作成してみてください。channel.on_datasend_data

ここでは使いたくないかもしれませんexec。Net :: SSH :: Connection :: Channelのドキュメントから:

指定されたコマンドを呼び出すように要求するチャネル要求を送信します。

コマンドを呼び出すのではなく、プロンプトに応答するためにテキスト文字列を送信する必要があります。ドキュメントにはexec、「ls -l/home」などの完全なCLIコマンドを送信するために使用されていることが示されています。

代わりに、send_dataおそらくあなたが望むものです。ドキュメントには、などの任意のテキストを送信するために使用されたことが示されていますchannel.send_data("the password\n")。ただし、ドキュメントの次の文に注意してください。

チャネルを介してデータをすぐに送信するのではなく、接続が次にデータを受け入れるときにパッケージ化されて送信される準備として、指定されたデータをチャネルの出力バッファに追加するだけであることに注意してください。

をご覧になることをお勧めしますchannel.request_pty。コンソールベースのアプリケーションとの対話用に設計されているようです。

通常は手動で行うSSHセッションを(本質的に)スクリプト化しようとしている場合は、-likeインターフェイスを使用する方が簡単な場合がありexpectます(たとえば、sshExpectのようなgemは試してみる価値があるかもしれません)。

于 2010-02-08T17:18:28.433 に答える
2

ポインタをありがとうございました。問題を突き止めることができました。channel.request_pty を使用する以外に、シェルを要求する必要もありました。以下は最終的に期待どおりに機能します。

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    
于 2010-02-08T21:03:30.890 に答える
0

私はNet::SSHライブラリにあまり詳しくないので、それ自体は手伝うことができませんが、Capistranoを使用して目的を達成できるようです。

たとえば、リモートサーバーに接続し、入力を予期して続行するコマンドを実行するcapistranoタスクがあります。CapistranoがリモートI/Oを処理します。多分それはあなたのための解決策かもしれませんか?

それが役に立てば幸い!

于 2010-02-08T16:56:29.397 に答える
0

私はそのlibに精通していませんが、SSHでは複数のチャネルを開くことができます。たぶん、サーバーは最初のデフォルトチャネルにのみ応答し、別のチャネルを開くと、新しいシェルを取得します。

于 2010-02-08T17:26:24.413 に答える
0

シェルで実行する"1\n"と、次のような応答が返されます。bash: 1: command not found

実行すると、次のようecho "1"になります。1

送信しているテキストを実行してよろしいですか?多分あなたは次のようなものを探していました:

output = ""
Net::SSH.start('host', 'user', :password => "pass") do |ssh|
   output = ssh.exec! "echo 1"
end
puts output
于 2010-02-08T17:10:55.190 に答える