2014-04-12 37 views
2

我要開始一個新的進程中去下列要求:在去啓動一個進程和分離從它

  • 起動過程應該運行轉到過程結束後也
  • 我需要能夠設置的運行它的Unix用戶/組
  • 我需要能夠設置環境變量繼承
  • 我需要在輸入/輸出控制性病/犯錯

下面是一個嘗試:

var attr = os.ProcAttr { 
Dir: "/bin", 
Env: os.Environ(), 
Files: []*os.File{ 
    os.Stdin, 
    "stdout.log", 
    "stderr.log", 
    }, 
} 
process, err := os.StartProcess("sleep", []string{"1"}, &attr) 

這工作得很好,但有從需求存在以下缺點:

  • 沒有辦法設置Unix用戶/組
  • 的啓動過程結束時轉到進程(父)停止

只有在簡化事情的情況下,才需要在Linux上運行。

+4

它看起來像你想要做的是分叉過程。 Go計劃中有這樣的警告請參閱此問題:https://code.google.com/p/go/issues/detail?id=227 – fabrizioM

+0

您無法在Go中使用fork()方法,特別是一旦運行時啓動並運行。子進程應該是負責從父進程中分離出來的進程,或者使用像「start-stop-daemon」這樣的包裝器。 – JimB

回答

5
  1. 您可以使用process.Release從父一個分離的子過程,使父母去世後,其生存
  2. 看的定義* os.ProcAttr.Sys.Credentials屬性:它看起來像使用該屬性可以設置處理用戶和組ID。

這裏就是你們的榜樣的工作版本(我沒有,如果進程ID的檢查一組,其中實際)

package main 

import "fmt" 
import "os" 
import "syscall" 

const (
    UID = 501 
    GUID = 100 
    ) 


func main() { 
    // The Credential fields are used to set UID, GID and attitional GIDS of the process 
    // You need to run the program as root to do this 
     var cred = &syscall.Credential{ UID, GUID, []uint32{} } 
    // the Noctty flag is used to detach the process from parent tty 
    var sysproc = &syscall.SysProcAttr{ Credential:cred, Noctty:true } 
    var attr = os.ProcAttr{ 
     Dir: ".", 
     Env: os.Environ(), 
     Files: []*os.File{ 
      os.Stdin, 
      nil, 
      nil, 
     }, 
      Sys:sysproc, 

    } 
    process, err := os.StartProcess("/bin/sleep", []string{"/bin/sleep", "100"}, &attr) 
    if err == nil { 

     // It is not clear from docs, but Realease actually detaches the process 
     err = process.Release(); 
     if err != nil { 
      fmt.Println(err.Error()) 
     } 

    } else { 
     fmt.Println(err.Error()) 
    } 
} 
1

我發現,似乎工作的跨平臺是重新用特殊標誌運行程序。在你的主程序中,檢查這個標誌。如果在啓動時出現,您就處於「分叉」狀態。如果不存在,用標誌重新運行命令。

func rerunDetached() error { 
    cwd, err := os.Getwd() 
    if err != nil { 
     return err 
    } 
    args := append(os.Args, "--detached") 
    cmd := exec.Command(args[0], args[1:]...) 
    cmd.Dir = cwd 
    err = cmd.Start() 
    if err != nil { 
     return err 
    } 
    cmd.Process.Release() 
    return nil 
} 

這將只需重新運行過程中與確切參數並追加--detached的論點。當您的程序啓動時,請檢查--detached標誌以瞭解是否需要致電rerunDetached。這有點像一個可憐的男人fork(),它將跨越不同的操作系統。

相關問題