Ruby Net / SSH - 启动远程Python脚本和分离

时间:2017-05-19 12:31:23

标签: python ruby ssh

我需要通过SSH启动远程Python脚本。远程计算机上的Python脚本需要执行一些文件操作,为模拟启动可执行文件(从几个小时到几天),收集结果并写入文件。

我使用Net-SSH exec!从Ruby启动脚本。我使用渠道来捕获STDERRSTDOUT

脚本运行正常,但现在我想从本地Ruby脚本中分离远程机器上运行的脚本。然后,我将直接在远程机器上检查模拟的状态。

我尝试使用nohup运行脚本。

Net::SSH.exec!("nohup python script.py args > out.log 2> err.log < /dev/null &")

脚本已分离,我立即恢复控制,但远程计算机上的脚本被杀死,我无法在后台找到该进程。

理想情况下,我会直接从Ruby启动模拟可执行文件,但我必须使用Python,因为我需要一些Ruby中没有的库。

上述方法是否正确?我可以将nohup与Net-SSH一起使用吗?

有更好的方法吗?

编辑:

  def self.ssh_exec!(ssh, cmd, log = nil)

    ssh.open_channel do |ch|

      ch.request_pty do |chan,success|
      end

      ch.exec(cmd) do |chan, success|
        raise "could not execute command" unless success

        # "on_data" is called when the process writes something to stdout
        chan.on_data do |c, data|
          log ? (log << data) : (puts data) 
        end

        # "on_extended_data" is called when the process writes something to stderr
        chan.on_extended_data do |c, type, data|
          log ? (log.error data) : (puts data) 
        end

        chan.on_close do
           puts 'Done'
        end
      end
    end    
   end  
然后我打电话给

  Net::SSH.start(aws_ip, user, options = aws_options) do |ssh|

    script = File.join(path, 'pyfoam_scripts', 'run_case.py')
    cmd = "source...; python #{script} #{dst_case}"
    RG::Utils.ssh_exec!(ssh, cmd, @logger)

    ssh.loop
  end

其中

:options => {:keys => path_to_key, 'key.pem'), 
                        :keepalive => true,
                        :timeout => 3000, 
                        :compression => true,
                        :compression_level => 6},

1 个答案:

答案 0 :(得分:0)

经过一些测试后,感谢评论,我意识到我的代码中有三个错误:

  1. 我正在使用channelsChannels用于与远程计算机建立通信,捕获输出,使用回调。在这种情况下,我不需要任何这个。
  2. Net::SSH.exec!等待命令完成。我需要发射并忘记。 (愚蠢的错误)
  3. ssh.loop不需要。见1.
  4. 修正上述错误后,它就像魅力一样。