防止 Ctrl+C 中断 Golang 中的 exec.Command

我注意到,exec.Command即使中断调用已通过signal.Notify. 我已经完成了以下示例来显示问题:


package main


import (

    "log"

    "os"

    "os/exec"

    "os/signal"

    "syscall"

)


func sleep() {

    log.Println("Sleep start")

    cmd := exec.Command("sleep", "60")

    cmd.Run()

    log.Println("Sleep stop")

}


func main() {

    var doneChannel = make(chan bool)


    go sleep()


    c := make(chan os.Signal, 1)

    signal.Notify(c, os.Interrupt)

    signal.Notify(c, syscall.SIGTERM)

    go func() {

        <-c

        log.Println("Receved Ctrl + C")

    }()


    <-doneChannel

}

如果在此程序运行时按下 Ctrl+C,它将打印:


2015/10/16 10:05:50 Sleep start

^C2015/10/16 10:05:52 Receved Ctrl + C

2015/10/16 10:05:52 Sleep stop

显示sleep命令被中断。Ctrl+C 被成功捕获,主程序没有退出,只是sleep命令受到影响。


知道如何防止这种情况发生吗?


翻阅古今
浏览 343回答 2
2回答

守着星空守着你

当您按下 时,shell 将向整个进程组发出信号ctrl+c。如果直接向父进程发送信号,子进程将不会收到信号。为防止 shell 向子进程发送信号,您需要在启动进程之前使用Setpgid和Pgid字段在其自己的进程组中启动命令syscall.SysProcAttrcmd := exec.Command("sleep", "60")cmd.SysProcAttr = &syscall.SysProcAttr{&nbsp; &nbsp; Setpgid: true,}

白衣染霜花

您可以忽略该syscall.SIGINT信号,然后它就不会传递给exec.Command.func main() {&nbsp; &nbsp; var doneChannel = make(chan bool)&nbsp; &nbsp; signal.Ignore(syscall.SIGINT)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; log.Println("Sleep start")&nbsp; &nbsp; &nbsp; &nbsp; cmd := exec.Command("sleep", "10")&nbsp; &nbsp; &nbsp; &nbsp; cmd.Run()&nbsp; &nbsp; &nbsp; &nbsp; log.Println("Sleep stop")&nbsp; &nbsp; &nbsp; &nbsp; doneChannel <- true&nbsp; &nbsp; }()&nbsp; &nbsp; <-doneChannel}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go