在Windows上使用Git Bash/MINGW64捕获CTRL-C [英] Catch CTRL-C on Windows using Git Bash / MINGW64 with Go

查看:196
本文介绍了在Windows上使用Git Bash/MINGW64捕获CTRL-C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用户按下CTRL-C时,我想在退出之前运行特定的代码.该代码在Go中,我想使用Git Bash/MINGW64在Windows上运行它.使用Go,我做到了

I want to run specific code before quitting when the user hits CTRL-C. The code is in Go and I want to run it on Windows using Git Bash / MINGW64. Using Go, I do

interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
// some goroutines get started here
// ...
for {
  select {
  case <-interrupt:
    // code which shall be run on CTRL-C
  }
}

在Windows上,当我使用Windows命令行时,这可以工作,但是我也希望它在MINGW64/Git Bash上也可以工作.

On Windows, this works when I use a Windows command line, but I want it to work on MINGW64/Git Bash as well.

我在 https://stackoverflow.com/a/31974985/1370397 上发现了

trap '' SIGINT

至〜/.bashrc捕获SIGINT信号,并防止bash终止我的程序.

to ~/.bashrc traps the SIGINT signal and prevents bash from terminating my program.

这在具有bash版本的MINGW32上对我有用

This works for me on MINGW32 with bash version

$ bash --version
GNU bash, version 3.1.20(4)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.

但是它不能在bash版本的MINGW64上运行

but it fails to work on MINGW64, bash version

$ bash --version
GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
[...]

在MINGW64或新的(git)bash版本上有什么区别?

What's different on MINGW64 or on that new (git) bash version?

为便于测试,下面是一个最小的示例,以查看行为差异:

For easier testing, here is a minimal example to see the behaviour differences:

package main

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

func cleanup(){
    for i:=0; i<3; i++ {
        fmt.Println("Cleaning up...")
        time.Sleep(500*time.Millisecond)
    }
}

func work() {
    for {
        fmt.Println("Working...")
        time.Sleep(300*time.Millisecond)
    }
}

func main() {
    interrupt := make(chan os.Signal, 1)
    signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)

    go work()

    for {
        select {
        case <-interrupt:
            fmt.Println("Interrupt received - calling cleanup()...")
            cleanup()
            fmt.Println("Quitting...")
            return
        }
        fmt.Println("Waiting...")
    }
}

MINGW32的输出(〜/.bashrc中带有陷阱''SIGINT):

Output from MINGW32 (with trap '' SIGINT in ~/.bashrc):

$ ./sigint.exe
Working...
Working...
Working...
Interrupt received - calling cleanup()...
Cleaning up...
Working...
Working...
Cleaning up...
Working...
Cleaning up...
Working...
Working...
Quitting...

cleanup()代码被执行.

The cleanup() code gets executed.

MINGW64的输出(也带有〜/.bashrc中的陷阱''SIGINT):

Output from MINGW64 (also with trap '' SIGINT in ~/.bashrc):

$ ./sigint.exe
Working...
Working...
Working...
Working...

cleanup()无法执行. :-(

cleanup() does not get executed. :-(

推荐答案

在Windows的Git Bash中使用winpty正确捕获信号.它与安装捆绑在一起,因此您所需要做的就是:

Use winpty to catch signals correctly in Git Bash for Windows. It comes bundled with the installation, so all you need to do is:

$ winpty ./my-program.exe

这篇关于在Windows上使用Git Bash/MINGW64捕获CTRL-C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆