最新消息:服务器现已从linode换到fzhost.net,且主题已从retina 0.2换为大前端D8

【已解决】go代码出错退出:exit status 1

GO crifan 121浏览 0评论

【问题】

折腾:

【已解决】go语言中实现输出内容到log文件

期间,结果用如下代码,至少看起来很正常的代码:

package main

import (
    "fmt"
    "log"
    "os"
    //"io/ioutil"
    //"net/http"
    "runtime"
    "path"
    "strings"
)

// GetCurFilename
// Get current file name, without suffix
func GetCurFilename() string {
    // var currentDir string
    // currentDir, err := os.Getwd()
    // fmt.Println("currentDir=%s", currentDir)
    // if err != nil {
        // fmt.Println("get current directory error=%s\n", err)
    // }

    _, fulleFilename, _, _ := runtime.Caller(0)
    //fmt.Println(fulleFilename)
    var filenameWithSuffix string
    filenameWithSuffix = path.Base(fulleFilename)
    //fmt.Println("filenameWithSuffix=", filenameWithSuffix)
    var fileSuffix string
    fileSuffix = path.Ext(filenameWithSuffix)
    //fmt.Println("fileSuffix=", fileSuffix)
    
    //filenameWithSuffix = "EmulateLoginBaidu"
    //fileSuffix = ".go"
    //filenameWithSuffix = "EmulateLoginBaidu.go.go.go"
    //fileSuffix = ".go"
    //filenameWithSuffix = "EmulateLoginBaidu.go.txt"
    //fileSuffix = ".go"
    var filenameOnly string
    filenameOnly = strings.TrimSuffix(filenameWithSuffix, fileSuffix)
    //fmt.Println("filenameOnly=", filenameOnly)
    
    return filenameOnly
}

func main() {
    fmt.Printf("this is EmulateLoginBaidu.go\n")
    
    var filenameOnly string
    filenameOnly = GetCurFilename()
    fmt.Println("filenameOnly=", filenameOnly)
    
    var logFilename string =  filenameOnly + ".log";
    fmt.Println("logFilename=", logFilename)
    //logfile,err: = os.OpenFile("/Users/cybercare/tmp/test.log",os.O_RDWR|os.O_CREATE,0666)
    //logFile, err: = os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777)
    //logFile, err: = os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777);
    logFile, err := os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777)
    if err != nil {
        fmt.Printf("open file error=%s\r\n", err.Error())
        os.Exit(-1)
    }

    defer logFile.Close()
    logger:=log.New(logFile,"\r\n", log.Ldate | log.Ltime | log.Llongfile)
    logger.Println("normal log 1")
    logger.Println("normal log 2")
    logger.Fatal("fatal 1")
    logger.Fatal("fatal 2")
    
    //var baiduMainUrl string
    //baiduMainUrl = "http://www.baidu.com/";
    //baiduMainUrl := "http://www.baidu.com/";
    // var baiduMainUrl string = "http://www.baidu.com/";
    // fmt.Printf("baiduMainUrl=%s\n", baiduMainUrl)
    // resp, err := http.Get(baiduMainUrl)
    // if err != nil {
        // fmt.Printf("http get response errror=%s\n", err)
    // }
    // defer resp.Body.Close()
    // body, err := ioutil.ReadAll(resp.Body)
    // fmt.Printf("body=%s\n", body)
}

运行结果却是:

D:\tmp\tmp_dev_root\go\src\github.com\user\EmulateLoginBaidu>go run EmulateLoginBaidu.go
this is EmulateLoginBaidu.go
filenameOnly= EmulateLoginBaidu
logFilename= EmulateLoginBaidu.log
exit status 1

如图:

go code run exit status 1

即:

exit status 1

【解决过程】

1.看了半天,感觉代码都是正常的啊。

2.即使出错,那么这行:

    if err != nil {
        fmt.Printf("open file error=%s\r\n", err.Error())
        os.Exit(-1)
    }

也该打印出对应的信息的。

3.后来的后来,是自己去看了看,当前文件夹下,其实已经生成了对应的log文件:

D:\tmp\tmp_dev_root\go\src\github.com\user\EmulateLoginBaidu\EmulateLoginBaidu.log

而且内容是:

2013/09/18 16:55:43 D:/tmp/tmp_dev_root/go/src/github.com/user/EmulateLoginBaidu/EmulateLoginBaidu.go:66: normal log 1

2013/09/18 16:55:43 D:/tmp/tmp_dev_root/go/src/github.com/user/EmulateLoginBaidu/EmulateLoginBaidu.go:67: normal log 2

2013/09/18 16:55:43 D:/tmp/tmp_dev_root/go/src/github.com/user/EmulateLoginBaidu/EmulateLoginBaidu.go:68: fatal 1

所以,才想到:

貌似是log输出时,用了:

logger.Fatal

而导致程序以为自己出现了致命错误,从而退出,不能正常继续执行的。

4.所以去找找log的语法:

Package log

中,也看到了解释:

The Fatal functions call os.Exit(1) after writing the log message.

The Panic functions call panic after writing the log message.

所以就很清楚了:

log中的Fatal,会调用os.Exit(1),会导致程序退出的。

所以也去试试Panic,把代码改为:

    defer logFile.Close()
    logger:=log.New(logFile,"\r\n", log.Ldate | log.Ltime | log.Llongfile)
    logger.Println("normal log 1")
    logger.Println("normal log 2")
    logger.Panic("panic 1")
    logger.Fatal("fatal 1")

然后运行结果是:

D:\tmp\tmp_dev_root\go\src\github.com\user\EmulateLoginBaidu>go run EmulateLoginBaidu.go
this is EmulateLoginBaidu.go
filenameOnly= EmulateLoginBaidu
logFilename= EmulateLoginBaidu.log
panic: panic 1

goroutine 1 [running]:
log.(*Logger).Panic(0xc080033370, 0x2d1e18, 0x1, 0x1)
        C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist675583351/go/src/pkg/log/log.go:193 +0xaa
main.main()
        D:/tmp/tmp_dev_root/go/src/github.com/user/EmulateLoginBaidu/EmulateLoginBaidu.go:68 +0x67b

goroutine 2 [runnable]:
exit status 2

如图:

go log panic panic 1

【总结】

至此,很清楚了:

go语言中的log模块:

Fatal函数会导致程序(调用os.Exit(1))退出->退出返回值为1

Panic函数会导致挂掉(且会打印出panic时的信息)并退出->退出返回值为2

即:

没事的时候,使用log输出信息的时候,不要随便乱用Panic或Fatal函数,否则会导致程序退出的。

正常输出信息,只用:Println,就可以了。

转载请注明:在路上 » 【已解决】go代码出错退出:exit status 1

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
51 queries in 0.497 seconds, using 12.91MB memory