在Golang中,如何用SIGTERM而不是SIGKILL终止os.exec.Cmd进程



当前,我正在使用Golangos.exc.Cmd.process.Kill((方法(在Ubuntu框上(终止一个进程。

这似乎立即终止了这个过程,而不是优雅地终止。我正在启动的一些进程也会写入文件,这会导致文件被截断。

我想使用SIGTERM而不是使用Golang的SIGKILL来优雅地终止进程。

下面是一个使用cmd启动然后终止的进程的简单示例。Process.Kill((,我想在Golang中找到一个Kill(((方法的替代方法,它使用SIGTERM而不是SIGKILL,谢谢!

import "os/exec"
cmd := exec.Command("nc", "example.com", "80")
if err := cmd.Start(); err != nil {
log.Print(err)
}
go func() {
cmd.Wait()
}()
// Kill the process - this seems to kill the process ungracefully
cmd.Process.Kill()

您可以使用Signal((API。支持的系统调用在这里。

所以基本上你可能想要使用

cmd.Process.Signal(syscall.SIGTERM)

此外,请根据文件说明。

上的操作系统包中保证存在的唯一信号值所有系统都是操作系统。中断(向进程发送中断(和os。Kill(强制进程退出(。在Windows上,发送操作系统。打断到带有os的进程。过程。信号未执行;它会回来的错误而不是发送信号。

cmd.Process.Signal(syscall.SIGTERM)

您可以使用:

cmd.Process.Signal(os.Interrupt)

测试示例:

package main
import (
"fmt"
"log"
"net"
"os"
"os/exec"
"sync"
"time"
)
func main() {
cmd := exec.Command("nc", "-l", "8080")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
err := cmd.Wait()
if err != nil {
fmt.Println("cmd.Wait:", err)
}
fmt.Println("done")
wg.Done()
}()
fmt.Println("TCP Dial")
fmt.Println("Pid =", cmd.Process.Pid)
time.Sleep(200 * time.Millisecond)
// or comment this and use: nc 127.0.0.1 8080
w1, err := net.DialTimeout("tcp", "127.0.0.1:8080", 1*time.Second)
if err != nil {
log.Fatal("tcp DialTimeout:", err)
}
defer w1.Close()
fmt.Fprintln(w1, "Hi")
time.Sleep(1 * time.Second)
// cmd.Process.Kill()
cmd.Process.Signal(os.Interrupt)
wg.Wait()
}

输出:

TCP Dial
Pid = 21257
Hi
cmd.Wait: signal: interrupt
done

最新更新