Goでプロセスを開始し、そこから切り離す 質問する

Goでプロセスを開始し、そこから切り離す 質問する

次の要件を満たす Go で新しいプロセスを開始する必要があります。

  • Goプロセスが終了した後も開始プロセスは実行される必要がある
  • 実行しているUnixユーザー/グループを設定できるようにする必要がある
  • 継承された環境変数を設定できるようにする必要がある
  • std in/out/errを制御する必要があります

ここに試みがあります:

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ユーザー/グループを設定する方法がない
  • 開始されたプロセスは、Goプロセス(親)が停止すると終了します。

物事を簡素化できる場合にのみ、これを Linux 上で実行する必要があります。

ベストアンサー1

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

おすすめ記事