Golang сигналы ловить

Я хочу реализовать "обертку процесса" в Go. В основном, что он будет делать, это запустить процесс (скажем, сервер узла) и контролировать его (перехватывать сигналы, такие как SIGKILL, SIGTERM ...)

Я думаю, что способ сделать это запустить сервер узла в рутине go с помощью syscall.Exec:

func launchCmd(path string, args []string) {
  err := syscall.Exec(path, args, os.Environ())
  if err != nil {
    panic(err)
  }
}

тогда я хотел бы поймать все возможные сигналы, генерируемые командой, выполняемой syscall. Я довольно Новичок, чтобы пойти, любая помощь будет оценена.

2 ответов


существует три способа выполнения программы в Go:

  1. syscall пакета с syscall.Exec, syscall.ForkExec, syscall.StartProcess
  2. os пакета с os.StartProcess
  3. С exec.Команда

syscall.StartProcess низкий уровень. Он возвращает uintptr как ручка.

os.StartProcess дает вам хороший os.Process структура, которую вы можете назвать сигнал on. os/exec дает io.ReaderWriter использовать на трубе. Оба используют syscall внутренне.

читать сигналы, посылаемые с процесс, отличный от вашего собственного, кажется немного сложным. Если бы это было возможно!--1--> смог бы это сделать. Я не вижу ничего очевидного в пакетах более высокого уровня.

для получения сигнала вы можете использовать сигнал.Уведомить такой:

sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
    syscall.SIGHUP,
    syscall.SIGINT,
    syscall.SIGTERM,
    syscall.SIGQUIT)
go func() {
    s := <-sigc
    // ... do something ...
}()

вам просто нужно изменить сигналы, которые вы заинтересованы в прослушивании. Если вы не укажете сигнал, он поймает все сигналы, которые могут быть захвачены.

можно использовать syscall.Убивать или


можно использовать сигнал.Уведомить :

import (
"os"
"os/signal"
"syscall"
)

func main() {
    signalChannel := make(chan os.Signal, 2)
    signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
    go func() {
        sig := <-signalChannel
        switch sig {
        case os.Interrupt:
            //handle SIGINT
        case syscall.SIGTERM:
            //handle SIGTERM
        }
    }()
    // ...
}