英文:
In Golang, how to terminate an os.exec.Cmd process with a SIGTERM instead of a SIGKILL?
问题
目前,我正在使用Golang的**os.exec.Cmd.Process.Kill()**方法终止一个进程(在Ubuntu上)。
这似乎会立即终止进程,而不是优雅地终止。我启动的一些进程还会写入文件,这会导致文件被截断。
我想使用Golang以SIGTERM而不是SIGKILL优雅地终止进程。
以下是一个简单的示例,启动并使用cmd.Process.Kill()终止进程,我希望有一个在Golang中使用SIGTERM而不是SIGKILL的Kill()方法的替代方法,谢谢!
import "os/exec"
cmd := exec.Command("nc", "example.com", "80")
if err := cmd.Start(); err != nil {
log.Print(err)
}
go func() {
cmd.Wait()
}()
// 终止进程 - 这似乎是非优雅地终止进程
cmd.Process.Kill()
英文:
Currently, I am terminating a process using the Golang os.exec.Cmd.Process.Kill() method (on an Ubuntu box).
This seems to terminate the process immediately instead of gracefully. Some of the processes that I am launching also write to files, and it causes the files to become truncated.
I want to terminate the process gracefully with a SIGTERM instead of a SIGKILL using Golang.
Here is a simple example of a process that is started and then terminated using cmd.Process.Kill(), I would like an alternative in Golang to the Kill() method which uses SIGTERM instead of SIGKILL, thanks!
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()
答案1
得分: 7
你可以使用Signal() API。支持的Syscalls在这里。
所以基本上你可能想要使用:
cmd.Process.Signal(syscall.SIGTERM)
另请注意,根据文档。
> 在所有系统上,os包中保证存在的唯一信号值是os.Interrupt(发送中断信号给进程)和os.Kill(强制进程退出)。在Windows上,使用os.Process.Signal向进程发送os.Interrupt信号没有实现;它会返回一个错误而不是发送信号。
英文:
You can use Signal() API. The supported Syscalls are here.
So basically you might want to use
cmd.Process.Signal(syscall.SIGTERM)
Also please note as per documentation.
> The only signal values guaranteed to be present in the os package on
> all systems are os.Interrupt (send the process an interrupt) and
> os.Kill (force the process to exit). On Windows, sending os.Interrupt
> to a process with os.Process.Signal is not implemented; it will return
> an error instead of sending a signal.
答案2
得分: 2
cmd.Process.Signal(syscall.SIGTERM)
这行代码是用于发送终止信号给进程的。
英文:
cmd.Process.Signal(syscall.SIGTERM)
答案3
得分: 1
你可以使用以下代码:
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
英文:
You may use:
cmd.Process.Signal(os.Interrupt)
Tested example:
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()
}
Output:
TCP Dial
Pid = 21257
Hi
cmd.Wait: signal: interrupt
done
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论