Go runtime mode config paths

Preface

  • In go language development, it is often necessary to obtain the program execution directory, such as when loading configuration files, writing debugging, error logs, etc.
  • The execution directories of go programs in development environment, production environment, and test environment are usually different, which makes it more troublesome to obtain the program execution directory in different situations.
  • Next, we will introduce several commonly used methods to obtain directories in the go language, and introduce their related features.

os.Getwd() returns the root path relative to one of the current directories

func GetCWD() string {
	cwd, _ := os.Getwd()
	return cwd
}

os.Executable() returns the absolute path of the executable file of the current process. The path will contain the name of the executable file, and filepath.Dir() will return the directory where the executable file is located.

func GetExec() string {
	exePath, _ := os.Executable()
	exePath, _ := os.Executable()
}

os.TempDir() returns the default path for storing temporary files

func GetTempDir() string {
	return os.TempDir()
}

runtime.Caller returns file and line number information about function calls on the calling goroutine stack

// 返回有关调用 goroutine 堆栈上的函数调用的文件和行号信息
func GetCaller() (string, int) {
	_, filename, line, ok := runtime.Caller(0)
	if ok {
		return path.Dir(filename), line
	}
	return "", 0
}

main.go complete code

package main

import (
	"fmt"

	"github.com/snowlyg/learns/path/dir"
)

func main() {
	fmt.Printf("cwd path is %s\n", dir.GetCWD())
	fmt.Printf("exec path is %s\n", dir.GetExec())
	path, line := dir.GetCaller()
	fmt.Printf("caller filepath is %s\ncaller line is %d\n", path, line)
}

dir/dir.go

// 返回相对当前目录之一的根路径
func GetCWD() string {
	cwd, _ := os.Getwd()
	return cwd
}

// 返回当前进程的可执行文件绝对路径
func GetExec() string {
	exePath, _ := os.Executable()
	return filepath.Dir(exePath)
}

// 返回存放临时文件的默认路径
func GetTempDir() string {
	return os.TempDir()
}

// 返回有关调用 goroutine 堆栈上的函数调用的文件和行号信息
func GetCaller() (string, int) {
	_, filename, line, ok := runtime.Caller(0)
	if ok {
		return path.Dir(filename), line
	}
	return "", 0
}
package dir

import (
	"testing"

	"fmt"
)

func TestPath(t *testing.T) {
	t.Run("cwd path", func(t *testing.T) {
		fmt.Printf("cwd path is %s\n", GetCWD())
		fmt.Printf("exec path is %s\n", GetExec())
		path, line := GetCaller()
		fmt.Printf("caller filepath is %s\ncaller line is %d\n", path, line)
	})
}

Next, let’s take a look at the data returned by each method in different modes.

  • The execution directory is /Users/snowlyg/go/src/github.com/snowlyg/learns, execute go run path/main.go go_run

  • The execution directory is /Users/snowlyg/go/src/github.com/snowlyg/learns, execute go build -o path/main path/main.go, and then execute the path/main execution file go_build

  • The execution directory is /Users/snowlyg/go/src/github.com/snowlyg/learns, execute go test -timeout 30s -v -run ^TestPath$ github.com/snowlyg/learns/path/dir go_test