登录
首页 >  Golang >  Go问答

Go信号处理程序避免处理终端窗口关闭

来源:stackoverflow

时间:2024-02-28 15:00:25 481浏览 收藏

编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《Go信号处理程序避免处理终端窗口关闭》,文章讲解的知识点主要包括,如果你对Golang方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。

问题内容

我用go编写了一个cli工具。当通过终端调用 cli 工具时,我希望该工具在调用 cleanup() 函数之前等待 ctrl+c 中断(sigint),然后最终退出。

但是,除了处理 sigint 之外,我还希望该工具能够处理用户简单关闭终端窗口的情况。如果它关闭,我希望调用相同的清理函数。这是我尝试过的示例。

package main

import (
    "fmt"
    "os"
    "syscall"
    "os/signal"
    "os/exec"
    "github.com/sirupsen/logrus"
)

func main() {
    // Parse the command-line argument.
    if len(os.Args) < 2 {
        logrus.Fatalf("Missing required argument")
    }
    arg := os.Args[1]

    logrus.Infof("Running with argument: %s", arg)

    // Set up signal handling.
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)

    done := make(chan bool, 1)
    go func() {
        sig := <-signals
        fmt.Println("")
        fmt.Println("Disconnection requested via Ctrl+C", sig)
        done <- true
    }()

    logrus.Infof("Press Ctrl+C to disconnect.")
    <-done

    cleanup()

    os.Exit(0)
}

func cleanup() {
    fmt.Println("Performing cleanup tasks...")
    touchFile := exec.Command("touch", "testfile.txt",)
    _, err := touchFile.CombinedOutput()

    if err != nil {
        println(err)
    }
}

这适用于用户通过 ctrl+c 发送中断并调用清理函数的情况,但当用户只是关闭窗口时永远不会调用清理函数。我认为包含 syscall.sighup 可以解决此问题。请指教。

编辑:我已经在默认的 macos 终端中对此进行了测试,关闭窗口时会调用清理函数,但使用 iterm 时不会调用清理函数。


正确答案


package main

import (
redacted
)

func main() {
    // Parse the command-line argument.
    if len(os.Args) < 2 {
        logrus.Fatalf("Missing required argument")
    }
    arg := os.Args[1]

    log.Infof("Running with argument: %s", arg)

    // Set up signal handling.
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)

    done := make(chan bool, 1)
    go func() {
        sig := <-signals
        fmt.Println("")
        fmt.Println("Disconnection requested via Ctrl+C", sig)
        done <- true
    }()

    log.Infof("Press Ctrl+C to disconnect.")
    <-done

    cleanup()

    os.Exit(0)
}

func cleanup() {
    fmt.Println("Performing cleanup tasks...")
    touchFile := exec.Command("touch", "testfile.txt",)
    _, err := touchFile.CombinedOutput()

    if err != nil {
        println(err)
    }
}

sigkill 的添加现在适用于 iterm。

好了,本文到此结束,带大家了解了《Go信号处理程序避免处理终端窗口关闭》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>