2016-08-08 11 views
9

Chcę uruchomić określony kod przed zakończeniem, gdy użytkownik trafi CTRL-C. Kod jest w Go i chcę go uruchomić w systemie Windows przy użyciu Git Bash/MINGW64. Korzystanie idź, jaCatch CTRL-C w systemie Windows przy użyciu Git Bash/MINGW64 z 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 
    } 
} 

W systemie Windows, to działa, kiedy używać wiersza polecenia systemu Windows, ale chcę go do pracy na MINGW64/Git Bash, jak również.

znalazłem na https://stackoverflow.com/a/31974985/1370397 że dodanie

trap '' SIGINT 

do ~/.bashrc wychwytuje sygnał SIGINT i zapobiega bash od zakończenia mój program.

Działa to dla mnie na mingw32 z bash wersji

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

ale to nie działa na MINGW64, wersja bash

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

Czym różni na MINGW64 lub na tej nowej (GIT) wersji bash ?

Dla łatwiejszego testowania, tutaj jest minimalny przykład aby zobaczyć różnice Zachowanie:

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

Wyjście z mingw32 (z pułapki '' SIGINT w ~/.bashrc):

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

The Kod cleanup() zostaje wykonany.

Wyjście z MINGW64 (również z pułapki '' SIGINT w ~/.bashrc):

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

porządki() nie zostanie wykonana. :-(

+1

Wydaje się, że ktoś o podobnej konfiguracji tutaj https : //sourceforge.net/p/mingw-w64/bugs/561/ Może warto zajrzeć do Keynana Pratta, o którym wspomniałem, że może to być bug GO, ale z tego, co powiedziałeś, może jest w MINGW64. Powinieneś dodać wskaźnik z powrotem do swojego posta. – JGFMK

+1

Błąd "Nie idź", tak naprawdę dzieje się również, jeśli spróbujesz tego samego w C. – Leandros

Odpowiedz

0

Zastosowanie winpty złapać sygnały poprawnie w Git Bash dla Windows To jest dostarczany wraz z instalacją, więc wszystko co musisz zrobić, to:.

$ winpty ./my-program.exe 
Powiązane problemy