web-dev-qa-db-ja.com

golang execバックグラウンドプロセスとそのpidの取得

状況:

自分自身をバックグラウンドに入れるコマンドを実行したい。それが可能であれば、コマンドをフォアグラウンドで実行し、自分でバックグラウンドに持ってきます。

質問:

プロセスがバックグラウンドで実行されている場合:Goを使用してpidを取得するにはどうすればよいですか?

私は以下を試しました:

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()

これはすぐに戻り、sshをバックグラウンドで実行したままにします。ただし、pidは、実行中のpidプロセスのsshではありません。さらに、フォークしてバックグラウンド化する前の親pidプロセスのsshです。

12
sbs

特別なことは必要ありません。sshにバックグラウンド自体を伝えないでください。また、Wait()を使わないでください。例:

$ 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は、goroutine待機を使用でき、プロセスを管理できます

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