为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
翻阅古今 2021-11-15 16:52:10
我注意到,exec.Command即使中断调用已通过signal.Notify. 我已经完成了以下示例来显示问题:package mainimport (    "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 + C2015/10/16 10:05:52 Sleep stop显示sleep命令被中断。Ctrl+C 被成功捕获,主程序没有退出,只是sleep命令受到影响。知道如何防止这种情况发生吗?
查看完整描述

2 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

当您按下 时,shell 将向整个进程组发出信号ctrl+c。如果直接向父进程发送信号,子进程将不会收到信号。


为防止 shell 向子进程发送信号,您需要在启动进程之前使用Setpgid和Pgid字段在其自己的进程组中启动命令syscall.SysProcAttr


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

cmd.SysProcAttr = &syscall.SysProcAttr{

    Setpgid: true,

}


查看完整回答
反对 回复 2021-11-15
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

您可以忽略该syscall.SIGINT信号,然后它就不会传递给exec.Command.


func main() {

    var doneChannel = make(chan bool)


    signal.Ignore(syscall.SIGINT)


    go func() {

        log.Println("Sleep start")

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

        cmd.Run()

        log.Println("Sleep stop")

        doneChannel <- true

    }()


    <-doneChannel

}


查看完整回答
反对 回复 2021-11-15
  • 2 回答
  • 0 关注
  • 342 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信