0

如何从.executeNet-SSH-Shell 中的方法获取标准输出

使用好的 'ol 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>

我需要一个可以使用的变量中的标准输出,并且我需要一个实际的有状态登录 shell,据我所知,准系统 Net-SSH 并没有这样做。

有任何想法吗?

编辑

按照@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

编辑

我认为问题在于!inexecute!因为以下对我来说很好:

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 回答