Можете ли вы запустить независимый экземпляр программы из Go?

Я ищу способ запустить полностью независимый экземпляр программы из программы Go. Пока это моя лучшая попытка:

  // Some code   

    go exec.Command("konsole", "--hold", "--separate", "sh", "-e", "go", "run", "test.go")
.Run()

    // Continue doing something else then quit

Использование Linux KDE's Konsole. Эта команда «почти» работает — она запускает новый экземпляр Konsole и запускает программу. Но они зависимы: если завершается первая программа (ctrl+c), то завершается и вторая. Есть ли способ обойти эту проблему?


person Fasmo    schedule 21.02.2020    source источник
comment
Это не имеет ничего общего с тем, что дочерний процесс (на самом деле дочерний элемент дочернего процесса) является программой Go.   -  person Adrian    schedule 21.02.2020
comment
@ Адриан, честно говоря, я изменил это на просто программу.   -  person Fasmo    schedule 21.02.2020
comment
Программа, работающая в фоновом режиме, независимая от той, из которой она была запущена, и ее потоки вывода закрыты или перенаправлены в файл журнала, называется демоном. Запуск процесса в качестве демона — это не просто одиночный вызов, но эти ключевые слова должны дать вам подсказку. Возможно, stackoverflow.com/questions/10027477/how-to- fork-a-process поможет.   -  person Ulrich Eckhardt    schedule 21.02.2020
comment
Если Ctrl-C является основной проблемой, вы можете просто поместить его в другую группу процессов.   -  person that other guy    schedule 21.02.2020


Ответы (1)


Для этого вам нужно заменить exec.Command call на os.StartProcess с дополнительными атрибутами процесса os.ProcAttr и syscall.SysProcAttr. Установка флага Setpgid и оставление Pgid со значением по умолчанию 0 достигает цели, как указано @that_other_guy.

package main

import (
        "fmt"
        "os"
        "os/exec"
        "syscall"
)

func main() {
        cmd, err := exec.LookPath("sleep")
        if err != nil {
                panic(err)
        }
        attr := &os.ProcAttr{
                Sys: &syscall.SysProcAttr{
                        Setpgid: true,
                },
        }
        process, err := os.StartProcess(cmd, []string{cmd, "1m"}, attr)
        if err != nil {
                panic(err)
        }
        fmt.Println(process.Pid)
        process.Release()
        for {
        }
        return
}
person Grzegorz Żur    schedule 21.03.2020