I need to start a new process in Go with the following requirements:
Here is an attempt:
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)
This works fine but has the following shortcomings from the requirements:
This needs to run on Linux only if that simplifies things.
We can use the & operator, and the nohup, disown, setsid, and screen commands to start a process detached from the terminal. However, to detach a process that has already started, we need to use the bg command after pausing the process using Ctrl+Z.
Use Ctrl + Z to suspend a program then bg to run the process in background and disown to detach it from your current terminal session.
Here is how you can detach a process from bash shell. If a given process is running in the foreground, press Ctrl+z to interrupt it. Then run it in the background. Finally, type disown along with job sequence number of the backgrounded job.
Here is a working version of your example (I did not check if process ID's where actually the one set )
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())
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With