2016-09-15 32 views
5

Chcę uruchomić komendę, która umieszcza się w tle (lub jeśli to sprawia, że ​​rzeczy są bardziej możliwe, uruchamiać polecenie w trybie pierwszoplanowym i samodzielnie je), i uzyskać pid z proces w tle. Jak mam to zrobić w Go? Próbowałem:golang exec proces w tle i pobierz jego pid

cmd := exec.Command("ssh", "-i", keyFile, "-o", "ExitOnForwardFailure yes", "-fqnNTL", fmt.Sprintf("%d:127.0.0.1:%d", port, port), fmt.Sprintf("%[email protected]%s", serverUser, serverIP)) 
cmd.Start() 
pid := cmd.Process.Pid 
cmd.Wait() 

zwraca Ten ~ natychmiast, pozostawia ssh działa w tle, ale PID nie jest PID procesu docierania ssh (przypuszczalnie jego pid procesu rodzic ssh przed rozwidloną i w tle; sama) .

Jak zrobić to poprawnie?

+0

Co masz na myśli przez "tło"? Kiedy 'Start()' twój 'Cmd' masz już oddzielny proces potomny (z właściwym' Process.Pid') działający równolegle do twojej aplikacji Go. Być może wystarczy usunąć '-f' z flag ssh? –

+1

Potrzebuję proces, aby kontynuować działanie po zakończeniu procesu go. Następnie muszę mieć możliwość zabicia w tle procesu ssh, dla którego będę musiał przechowywać jego pid. – sbs

+0

Hmm, faktycznie masz rację, proces trwa, jeśli nie czekam na to i po prostu zakończ. – sbs

Odpowiedz

9

Nie potrzebujesz niczego specjalnego, po prostu nie mów ssh samemu tło i nie Wait() za to. Przykład:

$ cat script.sh 
#!/bin/sh 
sleep 1 
echo "I'm the script with pid $$" 
for i in 1 2 3; do 
     sleep 1 
     echo "Still running $$" 
done 
$ cat proc.go 
package main 

import (
     "log" 
     "os" 
     "os/exec" 
) 

func main() { 
    cmd := exec.Command("./script.sh") 
    cmd.Stdout = os.Stdout 
    err := cmd.Start() 
    if err != nil { 
     log.Fatal(err) 
    } 
    log.Printf("Just ran subprocess %d, exiting\n", cmd.Process.Pid) 
} 
$ go run proc.go 
2016/09/15 17:01:03 Just ran subprocess 3794, exiting 
$ I'm the script with pid 3794 
Still running 3794 
Still running 3794 
Still running 3794 
+0

Witajcie, wasz przykład działa poprawnie, ale proces przechodzi w tryb 'S' po jego zakończeniu. Czy istnieje lepszy sposób osiągnięcia tych samych rezultatów? Gdzie mogę dostać pid, aby sprawdzić czy skończył. W moim przypadku nie potrzebuję wyjścia, ponieważ będzie plik dziennika zawierający wyniki, jeśli zakończy się pomyślnie –

+0

Czy będzie działać lepiej, jeśli użyję połączenia ssh? –