doubi8383 2016-08-08 08:33
浏览 280

在Windows上使用Git Bash / MINGW64捕获CTRL-C

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
  }
}

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

I found on https://stackoverflow.com/a/31974985/1370397 that adding

trap '' SIGINT

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

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.

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.
[...]

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...")
    }
}

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...

The cleanup() code gets executed.

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

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

cleanup() does not get executed. :-(

  • 写回答

1条回答 默认 最新

  • doulue7522 2018-01-18 14:34
    关注

    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
    
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?