web-dev-qa-db-fra.com

golang exec processus d'arrière-plan et obtenir son pid

Situation:

Je veux exécuter une commande qui se met en arrière-plan. Si cela le rend plus possible, je vais exécuter la commande au premier plan et la mettre en arrière-plan par moi-même.

Question:

Lorsque le processus s'exécute en arrière-plan: comment puis-je obtenir son pid en utilisant Go?

J'ai essayé ce qui suit:

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

Cela revient instantanément et laisse ssh s'exécuter en arrière-plan. Mais c'est pid n'est pas le pid du processus ssh en cours d'exécution. De plus, c'est le pid du processus parent ssh avant de se bifurquer et de se mettre en arrière-plan.

12
sbs

Vous n'avez besoin de rien de spécial, ne dites simplement pas à ssh de se mettre en arrière-plan et ne faites pas Wait() pour cela. Exemple:

$ 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
15
Roman Khimov

@Mostafa Hussein, peut utiliser l'attente de goroutine, gérer le processus

function main()
    cmd := exec.Command( "Shell.sh" )
    err := cmd.Start()
    if err != nil {
        return err
    }
    pid := cmd.Process.Pid
    // use goroutine waiting, manage process
    // this is important, otherwise the process becomes in S mode
    go func() { 
        err = cmd.Wait()
        fmt.Printf("Command finished with error: %v", err)
    }()
    return nil
}
1
Max