最初のコマンドの前に、ruby と Net::SSH を使用して SSH プロンプトに応答します。
質問
Net :: SSHを使用して、ログイン直後にユーザーからの入力が必要なスクリプトを実行するサーバーに接続しようとしています。ユーザーは「1」または「2」を入力する必要があり、その後端末経由でデータを受信します。
私の問題は、接続はできても、「1 」をサーバーに送信して出力を受信する方法がわからないことです。
次のコードは、「INFO -- net.ssh.connection.session[80906b74]」で停止します。チャンネルオープン確認:0 0 0 32768」。
channel.send_data の代わりに channel.exec( "1 " ) を使用しても、当然のことながら機能しません。
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
何かアイデアはありますか?
前もって感謝します
解決
あなたのことを確認してもらえますか? send_data
通話が発生しています 後 リモートサーバーからプロンプトを受け取りますか?を構築してみてください channel.on_data
あなたの周りをブロックする send_data
これにより、応答を送信する前にサーバーから予期したプロンプトが得られるかどうかを確認できます。
使いたくないかもしれません exec
ここ。Net::SSH::Connection::Channel のドキュメントから:
次のことを求めるチャネル要求を送信します。 指定されたコマンドが呼び出されます。
コマンドを呼び出すのではなく、プロンプトに応答するテキスト文字列を送信したいと考えています。ドキュメントは示しています exec
「ls -l /home」などの完全な CLI コマンドを送信するために使用されます。
その代わり、 send_data
おそらくあなたが望んでいることです。ドキュメントには、次のような任意のテキストを送信するために使用されていたことが示されています。 channel.send_data("the password\n")
. 。ただし、ドキュメント内の次の文に注意してください。
すぐには送信されないことに注意してください チャネル全体のデータですが、 代わりに、指定されたデータを追加するだけです チャネルの出力バッファに、 パッケージ化の準備と 次回の接続時に送信 はデータを受け付けています。
見てみるのもいいかもしれません channel.request_pty
. 。コンソールベースのアプリケーションとの対話用に設計されているようです。
通常は手動で実行する SSH セッションを (本質的に) スクリプト化しようとしている場合は、 expect
- のようなインターフェイス (たとえば、Gem のようなインターフェイス) sshExpect 試してみる価値はあるかも知れません)。
他のヒント
ポインタをありがとうございました。私はこの問題に私の指を置くことができました - 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
私は Net::SSH ライブラリにあまり詳しくないので、それ自体については役に立ちませんが、次を使用すると必要なことを達成できるようです カピストラーノ.
たとえば、リモートサーバーに接続し、入力を期待するコマンドを実行して続行するcapistranoタスクがあります。Capistrano はリモート I/O を処理します。もしかしたらそれが解決策になるかも?
それが役に立てば幸い!
"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
私はlibに習熟ないんだけど、SSHであなたは、複数のチャネルを開くことができます。たぶん、サーバーは最初のデフォルトのチャネルに応答し、あなたが別のものを開いた場合は、新鮮なシェルを取得します。