乐闻世界logo
搜索文章和话题

Golang 如何获取当前运行的文件的所在的目录?

9 个月前提问
5 个月前修改
浏览次数83

6个答案

1
2
3
4
5
6

在 Golang 中,我们可以使用 os 标准库中的 Executable 函数来获取当前正在执行的可执行文件的完整路径,然后使用 filepath 标准库中的 Dir 函数来从完整路径中提取出目录。

下面是一个如何获取当前运行文件所在目录的示例代码:

go
package main import ( "fmt" "os" "path/filepath" ) func main() { // 获取当前执行的可执行文件的路径 exePath, err := os.Executable() if err != nil { panic(err) } // 获取可执行文件所在的目录 exeDir := filepath.Dir(exePath) fmt.Println("当前运行文件的目录是:", exeDir) }

在这个例子中,我们首先调用了 os.Executable() 函数来获取可执行文件的完整路径。如果调用成功,它会返回路径字符串和 nil 错误。如果有错误发生,我们通过 panic 终止程序。获取到可执行文件的完整路径后,我们使用 filepath.Dir() 函数来从中提取出文件所在的目录。

执行上面的程序,它将打印出当前运行的可执行文件所在的目录。这对于许多需要相对于可执行文件定位资源文件的应用程序非常有用,例如配置文件和模板。

2024年6月29日 12:07 回复

编辑:从 Go 1.8(2017 年 2 月发布)开始,推荐的方法是os.Executable

func Executable() (string, error)

可执行文件返回启动当前进程的可执行文件的路径名。无法保证路径仍然指向正确的可执行文件。如果使用符号链接来启动进程,则结果可能是符号链接或其指向的路径,具体取决于操作系统。如果需要稳定的结果,path/filepath.EvalSymlinks 可能会有所帮助。

要仅获取可执行文件的目录,您可以使用path/filepath.Dir.

例子

shell
package main import ( "fmt" "os" "path/filepath" ) func main() { ex, err := os.Executable() if err != nil { panic(err) } exPath := filepath.Dir(ex) fmt.Println(exPath) }

旧答案:

你应该能够使用os.Getwd

shell
func Getwd() (pwd string, err error)

Getwd 返回与当前目录相对应的根路径名。如果当前目录可以通过多个路径到达(由于符号链接),Getwd 可能会返回其中任何一个。

例如:

shell
package main import ( "fmt" "os" ) func main() { pwd, err := os.Getwd() if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println(pwd) }
2024年6月29日 12:07 回复

这应该可以做到:

shell
import ( "fmt" "log" "os" "path/filepath" ) func main() { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Fatal(err) } fmt.Println(dir) }
2024年6月29日 12:07 回复

使用osext包

它提供的函数ExecutableFolder()返回当前运行的程序可执行文件所在文件夹的绝对路径(对于 cron 作业很有用)。它是跨平台的。

在线文档

shell
package main import ( "github.com/kardianos/osext" "fmt" "log" ) func main() { folderPath, err := osext.ExecutableFolder() if err != nil { log.Fatal(err) } fmt.Println(folderPath) }
2024年6月29日 12:07 回复

我从 Node.js 转向 Go。相当于 Go 中的 Node.js__dirname是:

shell
_, filename, _, ok := runtime.Caller(0) if !ok { return errors.New("unable to get the current filename") } dirname := filepath.Dir(filename)

该线程中还提到了一些其他内容以及为什么它们是错误的:

  • os.Executable()将为您提供当前运行的可执行文件的文件路径。这相当于process.argv[0]在 Node.js 中。__dirname如果您想获取子包的 ,则情况并非如此。
  • os.Getwd()会给你当前的工作目录。这相当于process.cwd()在 Node.js 中。当您从另一个目录运行程序时,这将是错误的。

最后,我建议不要为此用例引入第三方包。这是您可以使用的包:

shell
package current // Filename is the __filename equivalent func Filename() (string, error) { _, filename, _, ok := runtime.Caller(1) if !ok { return "", errors.New("unable to get the current filename") } return filename, nil } // Dirname is the __dirname equivalent func Dirname() (string, error) { filename, err := Filename() if err != nil { return "", err } return filepath.Dir(filename), nil }

请注意,我已调整runtime.Caller(1)为 1,因为我们想要获取调用的包的目录current.Dirname(),而不是包含该包的目录current

**更新 (12/23)**正如 @VonC下面指出的,当您运行go build并分发二进制文件时,runtime.Caller(0), 将继续是_您的目录_。这可能不是您想要的。此行为与 不同__dirname,后者将反映文件所在位置的目录名。Go 中的这种行为没有完美的等价物。

2024年6月29日 12:07 回复

如果你这样做:

shell
dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Fatal(err) } fmt.Println(dir)

当您使用 GoLand 等 IDE 运行程序时,您将获得 /tmp 路径,因为可执行文件将从 /tmp 保存并运行

我认为获取当前工作目录或“。”的最佳方法 是 :

shell
import( "os" "fmt" "log" ) func main() { dir, err := os.Getwd() if err != nil { log.Fatal(err) } fmt.Println(dir) }

os.Getwd **()**函数将返回当前工作目录。

2024年6月29日 12:07 回复

你的答案