我制作了一个命令行应用程序,在其中我正在压缩文件夹并在本地服务器上进行共享,以供其他人下载.我要做的是在关闭服务器后立即删除压缩文件夹的副本.这是我的代码:

func main() {
    //flag to specify whether we will be uploading folder or a single file
    zipped := flag.Bool("z",false,"Use for zipping folders and serving them as a single file on the server.(Deletes the zipped file once the server closes.)")
    save := flag.Bool("s",false,"Use with -z for saving the zipped files locally even after the server closes.")
    flag.Parse()


    if len(flag.Args())>0{

        if *zipped{
            fmt.Println("zipping...")
            flag.Args()[0]=ZipFile()

            if !(*save){
              //I expect this to remove the file when I hit ctrl+c on cmd  
              defer os.Remove(flag.Args()[0])   
                 }
        }
        http.HandleFunc("/",ShareFile)
        fmt.Printf("Sharing file on %s:8080\n",GetOutboundIP())

        log.Fatal(http.ListenAndServe(":8080",nil))
    }else{
        fmt.Println("Invalid usage. No file mentioned. Use wshare -h for help.")
    }

}

当我按下ctrl-c键时,程序退出,主功能关闭,因此不应该运行os.删除(xyz)是否执行?A tour of go表示,当函数返回时,defer执行表达式.在这里,我觉得梅因根本没有机会归还任何东西.

要实现我想要做的事情,解决办法是什么?我脑子里有一些解决方案,比如等待按键等等,但我希望这个程序超级简单,那么有没有一种方法可以在服务器关闭/程序退出时立即删除文件,而不需要我进一步输入呢?

推荐答案

这个问题已经在 comments 中得到了回答,但为了完整起见,我将在这里对其进行记录.

defer只有在使用它的程序和代码正常运行的情况下才能运行.另一方面,使用命令停止或终止程序会向该程序发送一个信号,然后异常终止该程序,这不允许该程序干净地运行所有defer条语句.

如果您想在操作系统终止时进行清理,您可以监听操作系统信号-基于the example here的代码:

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
  <- sigs
  cleanupAllTheThings()
  os.Exit(0)
}()

如果您从main开始调用它,它将使Goroutine在您的程序的整个生命周期中保持运行,监听操作系统信号.cleanupAllTheThings()函数需要写得尽可能快而不阻塞才能有效--你永远不知道操作系统什么时候会带着偏见终止你.

此外,这不会保护您免受拔出插件或内核panic 的影响,因此在启动时或在单独的清理脚本中对旧程序状态进行某种清理通常是有意义的.

Go相关问答推荐

如果添加构建标签,gopls将停止工作

Makefile:现有文件上没有这样的文件或目录,不加载环境变量

如何将泛型函数作为参数传递给golang中的另一个函数?

如何在另一个文件夹中使用Delve运行二进制文件?

Redis:尽管数据存在,但 rdb.Pipelined 中出现redis:nil错误

为什么标准库中的 IsSorted 会反向迭代切片?

你如何在 Golang 代码中测试 filepath.Abs​​ 失败?

如何在 Go 中编写示例测试?

为什么不同的 Wireguard 私钥会产生相同的公钥?

Go:从 ssl 证书中获取 'subject/unstructeredName' 的值

如何模仿联合类型

从 os.stdout 读取

有没有办法将 yaml node 添加到 golang 中现有的 yaml 文档中?

try 运行 docker-compose up -d 时出现错误

Golang - 无法从 pipped Windows 命令中获取结果

使用 delve 在容器中调试 Golang:container_linux.go:380:启动容器进程导致:exec:/dlv:stat /dlv:没有这样的文件或目录

出于某种原因,Golang (Go) AES CBC 密文被填充了 16 个 0x00 字节

如何在golang中使用ozzo验证进行时间最大验证

行之间的模板交替设计

Go 错误处理、类型断言和 net package包