Ruby产生一个对象方法

时间:2017-05-23 01:23:37

标签: ruby

我正试图找出一种方法来跟踪我创建的进程的状态。在我的脚本中,我首先创建了我的对象:

ov = OpenVASOMP :: OpenVASOMP.new({“host”=>“localhost”,“port”=>“9390”,“user”=>“admin”,“password”=>“ #{ENV [ “OV”]}“})

创建一个ov对象并公开一堆其他方法。特别是:ov.task_start

我需要能够跟踪进程并在其运行时执行其他操作,例如将状态更新发送到远程服务器。

我最初的想法是将其包裹在Process.spawn中并跟踪PID,但这会引发错误:

 TypeError: no implicit conversion of REXML::Element into String

并且堆栈跟踪指向此行:pid = Process.spawn(ov.task_start(taskid))

所以,我猜你不能将对象及其方法传递给spawn

这是我的整个代码块,以防我还缺少其他东西:

ov = OpenVASOMP::OpenVASOMP.new({"host" => "localhost", "port" => "9390", "user" => "admin", "password" => "#{ENV["OV"]}"})
taskid = ov.task_create({"name" => timestamp, "target" => target, "config" => config})
running = true
pid = Process.spawn(ov.task_start(taskid))
Signal.trap("HUP") { log("#{results_dir}/events.log", "[!] Stop triggered by user!"); exit }
until running == false
  begin
    running = Process.getpgid(pid)
    log("#{results_dir}/events.log", "Scan PID: #{pid}")
    stat = ov.task_get_byid(taskid)
    update_ov_status(stat['progress'])
    log("#{results_dir}/events.log", "[+] Sending progress to server: #{stat['progress']}%")

    scan_status = get_scan_status

    if scan_status == "Stopped"
      ov.task_stop(taskid)
      ov.task_delete(taskid)
      ov.target_delete(target)
      Process.kill("HUP", pid)
      Process.wait
      update_task_id("")
      update_ov_status(0)
      update_scan_status("Idle")
    end

    sleep 60

  rescue Errno::ESRCH
    running = false
    puts "PID: #{pid} done!"
    log("#{results_dir}/events.log", "[!] Scan complete")
  end
end

task_start看起来像:

    def task_start (task_id) 
        xmlreq=xml_attr("start_task",{"task_id" => task_id}).to_s()
        begin
            xr=omp_request_xml(xmlreq)
        rescue 
            raise OMPResponseError
        end
        return xr
    end

我是不是错了?

1 个答案:

答案 0 :(得分:0)

在答案中重复我在评论中所说的内容,以便结束。

由于task_start不是shell脚本字符串,而是应该异步执行的代码块,因此请使用Process.fork { ov.task_start taskid }代替Process.spawn

Process.fork调用返回一个可用于停止进程的PID,例如:

# in one terminal
ruby -e "puts Process.fork { loop { puts('tick'); sleep 1 } }"
# it then prints a PID like 20626
# then in another terminal:
kill -9 20626
# the "tick" will stop getting printed every second.