Служба (работающая как deamon, ее можно найти с помощью systemctl, но не ps, например) команда (см. код), запускающая исполняемый файл (не уверен, стоит ли его упоминать, но на самом деле это один и тот же исполняемый файл в смысле кода).
Управление службами осуществляется с помощью github.com /kardianos/service.
Как часть кода, который запускает дочерняя служба, мне нужно остановить родительскую службу (service.control("stop")). В этот момент дочерний процесс также терпит неудачу вместо того, чтобы продолжить остальную часть потока.
Я попробовал:
- < li>установить идентификатор сеанса (Setsid=true)
- установить идентификатор группы (Setpgid-true)
- вызов Release() в базовом процессе после вызова Start()
- комбинации вышеперечисленного (как предложено здесь https://groups.google.com/g/golang-nuts/c/Jx-ZsdQIMJA)
код функции, которая инициирует процесс (примечание: это смесь того, что я пробовал. Я также пробовал их отдельно и т. д.):
func ExecuteCommandAsync(command, args string, detach bool) error {
logger.Notify("Running cli command:", command, args)
cmd := exec.Command(command, args)
if detach {
logger.Notify("Detaching from parent process")
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true, // new session id prevents sigkill to parent kill the child
//Setpgid: true, // new group id prevents sigkill to parent kill the child
}
}
err := cmd.Start()
if err != nil {
logger.Error("Failed running cli command:", command, err)
return err
}
if detach {
logger.Notify("Detached from parent process - releasing child process")
err = cmd.Process.Release()
if err != nil {
return err
}
} else {
go func() {
logger.Notify("Waiting for cli command to finish")
waitErr := cmd.Wait()
if waitErr != nil {
logger.Error("Error waiting for cli command to finish:", waitErr)
} else {
logger.Notify("Command finished successfully")
}
}()
}
return nil
}
код функции, останавливающей службу:
func systemStopService(s service.Service) error {
if s == nil {
return errors.New("stopService - service is nil")
}
logger.Notify(s.String() + " Stopping service")
err := service.Control(s, "stop")
if err == nil {
logger.Notify(s.String() + " Service stopped")
} else if strings.Contains(err.Error(), "service does not exist") ||
strings.Contains(err.Error(), "service has not been started") {
logger.Notify(s.String() + err.Error())
err = nil // not an error
} else {
logger.Error(s.String()+" Failed to stop service", err)
}
return err
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... ith-parent
Мобильная версия