0

.executeNet-SSH-Shellのメソッドから stdout を取得するにはどうすればよいですか

古き良き Net-SSH を使えば、これは簡単です

Net::SSH.start('host','user') do |ssh|
     puts ssh.exec! 'date'
end

私に与えますTue Jun 19 23:43:53 EDT 2012

しかし、シェルを使用しようとすると、プロセス オブジェクトが取得されます

Net::SSH.start('host','user') do |ssh|
    ssh.shell do |bash|
        output = bash.execute! 'ls'
        puts output
    end
end

私に与えます#<Net::SSH::Shell::Process:0x007fc809b541d0>

標準出力を簡単に取得する方法について、まばらなドキュメントには何も見つかりません。方法はありますが、その方法on_outputを使用しても効果がないようですexecute!

私も.execute!好きにブロックを渡そうとしました

bash.execute! 'ls' do |output|
    puts output
end

しかし、私はまだプロセスを取得します#<Net::SSH::Shell::Process:0x007fc809b541d0>

使用できる変数に標準出力が必要であり、実際のステートフル ログイン シェルが必要です。

何か案は?

編集

@vikhyatの提案と同じアイデアに沿って、私は試しました

 ssh.shell do |bash|
      process = bash.execute! 'ls'  do |a,b|
            # a is the process itself, b is the output
            puts [a,b]
            output = b
      end
 end

しかしb、コマンドが結果を返すことがわかっている場合でも、常に空です。

4

2 に答える 2

4

このようにしてみましたか?

Net::SSH.start('host','user') do |ssh|
    ssh.shell do |bash|
        process = bash.execute! 'ls'
        process.on_output do |a, b|
          # a is the process itself, b is the output
          p [a, b]
        end
    end
end

ここで Net::SSH::Process の定義を見ることができます: https://github.com/mitchellh/net-ssh-shell/blob/master/lib/net/ssh/shell/process.rb

編集

以下は私にとってはうまくいくので、問題は!in にあると思います:execute!

require 'net/ssh'
require 'net/ssh/shell'

Net::SSH.start('students.iitmandi.ac.in', 'k_vikhyat') do |ssh|
  ssh.shell do |bash|
    process = bash.execute 'whoami'
    process.on_output do |a, b|
      p b
    end
    bash.wait!
    bash.execute! 'exit'
  end
end

execute!プロセスを作成し、実行wait!してプロセスを返すように見えるため、なぜそうなのかはわかりません。

于 2012-06-20T09:26:48.910 に答える
1

次のラッパーを使用しています

def ssh_exec!(ssh, command)
    stdout_data = ""
    stderr_data = ""
    exit_code = nil
    exit_signal = nil

    ssh.open_channel do |channel|
      channel.exec(command) do |ch, success|
        unless success
          abort "FAILED: couldn't execute command (ssh.channel.exec)"
        end

        channel.on_data do |ch,data|
          stdout_data+=data
        end

        channel.on_extended_data do |ch,type,data|
          stderr_data+=data
        end

        channel.on_request("exit-status") do |ch,data|
          exit_code = data.read_long
        end

        channel.on_request("exit-signal") do |ch, data|
          exit_signal = data.read_long
        end
      end
    end
    ssh.loop
    [stdout_data, stderr_data, exit_code, exit_signal]
  end

そして使用法:

Net::SSH.start(@ssh_host, @ssh_user, :password => @ssh_password) do |ssh|
  result = ssh_exec! ssh, command
end

いつかSOかどこかで見つけましたが、今は覚えていません。

于 2012-06-20T14:04:05.630 に答える