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

时间:2013-08-30 16:07:43

标签: go

在nodejs中我使用__dirname。在Golang中,这相当于什么?

我用Google搜索并发现了这篇文章http://andrewbrookins.com/tech/golang-get-directory-of-the-current-file/。他使用以下代码的地方

_, filename, _, _ := runtime.Caller(1)
f, err := os.Open(path.Join(path.Dir(filename), "data.csv"))

但这是在Golang中做的正确方式还是惯用方式?

10 个答案:

答案 0 :(得分:232)

编辑:截至Go 1.8(2017年2月发布),推荐的方法是使用os.Executable

  

func Executable() (string, error)

     

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

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

Example

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

func Getwd() (pwd string, err error)
  

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

例如:

package main

import (
    "fmt"
    "os"
)

func main() {
    pwd, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    fmt.Println(pwd)
}

答案 1 :(得分:187)

这应该这样做:

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)
}

答案 2 :(得分:55)

使用包osext

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

Online documentation

package main

import (
    "github.com/kardianos/osext"
    "fmt"
    "log"
)

func main() {
    folderPath, err := osext.ExecutableFolder()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(folderPath)
}

答案 3 :(得分:6)

filepath.Abs("./")
  

Abs返回路径的绝对表示。如果路径不是   绝对它将与当前工作目录一起转向   它成为一条绝对的道路。

如评论中所述,这将返回当前处于活动状态的目录。

答案 4 :(得分:3)

如果你使用 kardianos osext ,你需要在本地测试,就像Derek Dowling评论的那样:

  

这很好用,直到你想用go run main.go来使用它   地方发展。不确定如何最好地解决这个问题   每次都预先构建一个可执行文件。

解决方案是制作gorun.exe实用程序而不是使用go run。 gorun.exe实用程序将使用" go build"编译项目,然后在项目的正常目录中运行它。

我和其他编译器有这个问题并发现自己制作这些实用程序,因为它们没有随编译器一起提供......特别是使用像C这样的工具,你必须编译和链接然后运行它(太多的工作) )。

如果有人喜欢我对gorun.exe(或elf)的想法,我很快就会把它上传到github ..

对不起,这个答案是作为评论,但由于我没有足够的声誉,我无法发表评论。

或者," go run"可以修改(如果它还没有这个功能)有一个参数,如"去运行-notemp"不在临时目录(或类似的东西)中运行程序。但我宁愿只输入gorun或" gor"因为它比复杂的参数短。需要将Gorun.exe或gor.exe安装在与go编译器相同的目录中

实现gorun.exe(或gor.exe)将是微不足道的,因为我只用几行代码就用其他编译器完成了...(着名的遗言; - )

答案 5 :(得分:3)

如果使用这种方式:

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

使用诸如GoLang之类的IDE运行程序时,您将获得/ tmp路径,因为可执行文件将从/ tmp保存并运行

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

import(
  "os" 
  "fmt"
  "log"
)

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

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

答案 6 :(得分:1)

dir, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
    }

这是针对golang版本的:go version go1.13.7 linux/amd64

为我工作,go run main.go。如果我运行go build -o fileName,并将最终的可执行文件放在其他文件夹中,则在运行可执行文件时会给出该路径。

答案 7 :(得分:0)

os.Executablehttps://tip.golang.org/pkg/os/#Executable

filepath.EvalSymlinkshttps://golang.org/pkg/path/filepath/#EvalSymlinks

完整演示:

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    var dirAbsPath string
    ex, err := os.Executable()
    if err == nil {
        dirAbsPath = filepath.Dir(ex)
        fmt.Println(dirAbsPath)
        return
    }

    exReal, err := filepath.EvalSymlinks(ex)
    if err != nil {
        panic(err)
    }
    dirAbsPath = filepath.Dir(exReal)
    fmt.Println(dirAbsPath)
}

答案 8 :(得分:0)

有时候这已经足够了,firs参数将始终是文件路径     包主

import (
    "fmt"
    "os"
)


func main() {
    fmt.Println(os.Args[0])
}

答案 9 :(得分:0)

古斯塔沃·尼迈耶(Gustavo Niemeyer)的回答很棒。 但是在Windows中,运行时proc主要位于另一个目录中,如下所示:

"C:\Users\XXX\AppData\Local\Temp"

如果您使用相对文件路径,例如"/config/api.yaml",它将使用代码所在的项目路径。