Current Working Directory

Preface

  • It is often necessary to get the current working directory in go language development, such as when you need to load configuration files, write debugging, error logs, etc.
  • The current working directory of a go program is usually different in development, production, and test environments, which makes it troublesome to get the current working directory of the program under different circumstances.
  • Next, we will introduce several common methods of getting the current working directory in go language, and introduce their related features.

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

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

os.Executable() returns the absolute path to the executable of the current process

The path will contain the name of the executable file. In conjunction with filepath.Dir() returns the directory where the executable is located.

1
2
3
4
func GetExec() string {
    exePath, _ := os.Executable()
    exePath, _ := os.Executable()
}

os.TempDir() returns the default path where temporary files are stored

1
2
3
func GetTempDir() string {
    return os.TempDir()
}

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

1
2
3
4
5
6
7
8
// Returns information about the file and line number of the function call on the calling goroutine stack.
func GetCaller() (string, int) {
    _, filename, line, ok := runtime.Caller(0)
    if ok {
        return path.Dir(filename), line
    }
    return "", 0
}

main.go Complete Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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 look at the data returned by each method in different modes

  • The current working directory is /Users/snowlyg/go/src/github.com/snowlyg/learns and execute go run path/main.go

    Get the current working directory

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

    Get the current working directory

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

    Get the current working directory

Ref

  • https://blog.snowlyg.com/dir/