2017-05-23 2 views
0

Ich versuche, einen Weg zu finden, den Status eines Prozesses zu verfolgen, den ich erstellt habe. In meinem Skript beginne ich mit der Erstellung meines Objekts:Ruby spawn eine Objektmethode

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

Das erstellt ein ov Objekt und stellt eine Reihe anderer Methoden zur Verfügung. Insbesondere: ov.task_start.

Ich muss in der Lage sein, den Prozess zu verfolgen und andere Aktionen auszuführen, während es ausgeführt wird, z. B. das Senden einer Statusaktualisierung an einen Remote-Server.

Mein erster Gedanke war, dies in einem Process.spawn zu wickeln und die PID zu verfolgen, aber das ist zu werfen einen Fehler:

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

und die Stack-Trace zeigt auf dieser Linie: pid = Process.spawn(ov.task_start(taskid))

Also, ich denke Sie können keine Objekte und ihre Methoden in spawn übergeben?

Hier ist meine ganze Code-Block, falls es etwas anderes ist, dass ich fehle:

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 

Und task_start wie folgt aussieht:

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 

Bin ich über dieses alles falsch gehen?

+0

es ist unklar, was 'ov.task_start (taskid)' kehrt zurück. [Process.spawn] (https://ruby-doc.org/core-2.2/Process.html#method-c-spawn) nimmt einen Shell-Befehl (string) als Argument. Es gibt auch Process.fork, das einen beliebigen Block akzeptiert (siehe [how-do-you-spawn-a-child-process-in-ruby] (https://stackoverflow.com/questions/307070/how-do-you- spawn-a-child-process-in-ruby)) –

+0

@maxpleaner Ich habe die Frage mit dem Inhalt von 'task_start' aktualisiert. Ich habe bisher noch keine Prozesskontroll-Ruby-Funktionen benutzt. Kann ich mit 'Fork 'die PID nachverfolgen? – Godzilla74

+0

Es tut es. Ich habe gerade überprüft, und die von Process.fork zurückgegebene pid kann an 'kill -9' übergeben werden, um es zu stoppen. Vielleicht würde 'pid = Process.fork {ov.task_start (taskid)}' für dich funktionieren. –

Antwort

0

Wiederholen Sie einfach, was ich in dem Kommentar in einer Antwort für den Abschluss sagte.

Da es sich bei task_start nicht um eine Shell-Skriptzeichenfolge handelt, sondern um einen Block von Code, der asynchron ausgeführt werden sollte, verwenden Sie Process.fork { ov.task_start taskid } anstelle von Process.spawn.

Der Process.fork Aufruf gibt eine PID, die verwendet werden können, um den Prozess zu stoppen, zum Beispiel:

# 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.