2016-09-15 6 views
5

自分自身をバックグラウンドに置くコマンドを実行したい(または、それが可能な場合は、コマンドをフォアグラウンドモードで実行して自分自身でバックグラウンドで実行する)。そして、バックグラウンドプロセスどのようにGoでこれを行うのですか? 、即座〜golang execバックグラウンドプロセスとその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() 

これは返すバックグラウンドで実行されているSSHを残したが、pidは実行中のsshプロセスのpidではありません(それはフォークの前に親のsshプロセスのおそらくそのPIDと自身をバックグラウンドに):私が試しました。

これを正しく行うにはどうすればよいですか?

+0

「背景」とはどういう意味ですか?あなたの 'Cmd'を' Start() 'すると、Goアプリケーションと同時に実行される別々の子プロセス(適切な' Process.Pid'を持つ)が既に存在します。たぶんsshフラグから '-f'を削除するだけでいいですか? –

+1

私のゴープロセスが終了してからプロセスを実行し続ける必要があります。私は、将来、バックグラウンドを持つsshプロセスをkillする必要があります。そのためには、pidを保存しておく必要があります。 – sbs

+0

ええと、実際にあなたが正しいです、もし私がそれを待っていなくてもプロセスは続行し、ただ終了します。 – sbs

答えて

9

特別なことは必要ありません。単に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 
+0

こんにちは、あなたの例は正しく動作していますが、プロセスは終了後に 'S'モードになります。同じ結果を達成するより良い方法はありますか?完成したかどうか確認するためにどこでpidを得ることができますか?私の場合は、正常に終了した場合、結果を含むログファイルが存在するため、出力は必要ありません。 –

+0

ssh接続を使用するとうまく動作しますか? –

関連する問題