我希望在用户点击CTRL-C之前运行特定代码。代码在Go中,我想使用Git Bash / MINGW64在Windows上运行它。使用Go,我做
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。
我在https://stackoverflow.com/a/31974985/1370397上发现添加了
trap '' SIGINT
to~ / .bashrc捕获SIGINT信号并阻止bash终止我的程序。
这适用于使用bash版本的MINGW32
$ bash --version
GNU bash, version 3.1.20(4)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.
但它无法在MINGW64,bash版本
上运行$ bash --version
GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
[...]
MINGW64或新的(git)bash版本有什么不同?
为了便于测试,以下是查看行为差异的最小示例:
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中有陷阱&#39; SIGINT):
$ ./sigint.exe
Working...
Working...
Working...
Interrupt received - calling cleanup()...
Cleaning up...
Working...
Working...
Cleaning up...
Working...
Cleaning up...
Working...
Working...
Quitting...
执行cleanup()代码。
MINGW64的输出(也有陷阱&#39;&〜/ .bashrc中的SIGINT):
$ ./sigint.exe
Working...
Working...
Working...
Working...
cleanup()没有被执行。 : - (
答案 0 :(得分:4)
使用winpty
在Git Bash for Windows中正确捕获信号。它与安装捆绑在一起,所以您需要做的就是:
$ winpty ./my-program.exe