在Ctrl+C时退出Go程序

huangapple go评论89阅读模式
英文:

Exit Go program on Ctrl+C

问题

我在使用<kbd>Ctrl</kbd>+<kbd>C</kbd>取消程序时遇到了一些困难。我觉得我对通道的理解可能有些偏差,因为我无法理解为什么当程序提示输入密码后,按下<kbd>Ctrl</kbd>+<kbd>C</kbd>时程序不会关闭。

有人能解释一下为什么在要求输入“密码”并按下<kbd>Ctrl</kbd>+<kbd>C</kbd>后程序不会退出吗?

package main

import (
    "fmt"
    "os"
    "os/user"
    "os/signal"
    "syscall"
    "github.com/howeyc/gopass"
)

func main() {
    signalChannel := make(chan os.Signal, 2)
    signal.Notify(signalChannel, os.Interrupt, syscall.SIGINT)
    go func() {
        sig := <-signalChannel
        switch sig {
        case os.Interrupt:
            os.Exit(0)
        case syscall.SIGINT:
            os.Exit(0)
        }
    }()

    user, _ := user.Current()
    fmt.Printf("Hi %s, password please: ", user.Username)
    pass := gopass.GetPasswd()
    fmt.Printf("Recieved as: %s\r\n", pass)
}

感谢任何帮助。更新:我通过切换到https://github.com/seehuhn/password来解决了这个问题,该库可以监听信号。

英文:

I am having some difficulties cancelling my program with <kbd>Ctrl</kbd>+<kbd>C</kbd>. I believe my knowledge of channels must be a bit off as I can't wrap my head around why this program won't close with <kbd>Ctrl</kbd>+<kbd>C</kbd> when it prompts for the password.

Would anyone be able to say why it won't exit after asking for the "Password" and pressing <kbd>Ctrl</kbd>+<kbd>C</kbd>?

package main

import (
    &quot;fmt&quot;
    &quot;os&quot;
    &quot;os/user&quot;
    &quot;os/signal&quot;
    &quot;syscall&quot;
    &quot;github.com/howeyc/gopass&quot;
)

func main() {
    signalChannel := make(chan os.Signal, 2)
    signal.Notify(signalChannel, os.Interrupt, syscall.SIGINT)
    go func() {
        sig := &lt;-signalChannel
        switch sig {
        case os.Interrupt:
            os.Exit(0)
        case syscall.SIGINT:
            os.Exit(0)
        }
    }()

    user, _ := user.Current()
    fmt.Printf(&quot;Hi %s, password please: &quot;, user.Username)
    pass := gopass.GetPasswd()
    fmt.Printf(&quot;Recieved as: %s\r\n&quot;, pass)
}

Any help is appreciated, thanks.

Update

I resolved this by switching to https://github.com/seehuhn/password which listens for signals

答案1

得分: 4

Ctrl-C 是 SIGINT。Ctrl-\ 是 SIGQUIT(默认情况下)。您需要更改应用程序监听的信号。

这个答案中有关于终端中信号的典型快捷方式的一些详细信息:https://superuser.com/a/343046/93194


更新:gopass 干扰了您的信号处理。考虑使用 http://godoc.org/code.google.com/p/go.crypto/ssh/terminal#ReadPassword 替代:

    state, err := terminal.MakeRaw(0)
    if err != nil {
        log.Fatal(err)
    }
    defer terminal.Restore(0, state)
    term := terminal.NewTerminal(os.Stdout, ">")
    password, err := term.ReadPassword("请输入密码:")
    if err != nil {
        log.Fatal(err)
    }
英文:

Ctrl-C is SIGINT. Ctrl-\ is SIGQUIT (by default). You will want to change the signal your application listens for.

This answer has some further details on the typical (but some implementations may stray) shortcuts for signals in a terminal: https://superuser.com/a/343046/93194


Update: gopass is interfering with your signal handling. Look at using http://godoc.org/code.google.com/p/go.crypto/ssh/terminal#ReadPassword instead:

    state, err := terminal.MakeRaw(0)
    if err != nil {
        log.Fatal(err)
    }
    defer terminal.Restore(0, state)
    term := terminal.NewTerminal(os.Stdout, &quot;&gt;&quot;)
    password, err := term.ReadPassword(&quot;Enter password: &quot;)
    if err != nil {
        log.Fatal(err)
    }

huangapple
  • 本文由 发表于 2014年7月7日 18:15:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/24608210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定