问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

彻底解决Golang获取当前项目绝对路径问题

发布网友 发布时间:22小时前

我来回答

1个回答

热心网友 时间:22小时前

由于Golang是编译型语言,获取当前执行目录变得复杂。传统做法是通过启动传参或环境变量手动传递路径,但今天发现了一种更便捷的解决方案。

Go程序有两种执行方式:go run和go build。这两种方式在获取当前执行路径时会产生不同的问题。

下面直接展示代码示例。我们编写一个获取当前可执行文件路径的方法,然后通过go run和go build两种方式来测试。

通过对比执行结果,我们发现go run获取到的路径是错误的。原因是go run会将源代码编译到系统TEMP或TMP环境变量目录中并启动执行,而go build只会在当前目录编译出可执行文件,并不会自动执行。

我们可以简单理解为,go run main.go等价于go build & ./main。虽然两种执行方式最终都是一样的过程,但他们的执行目录却完全不一样了。

在我查看服务日志(zap库)时,发现了一种新的解决方案。比如一条简单的日志,服务是通过go run启动的,但日志库却正确地打印出了程序路径D:/Projects/te-server/modules/es/es.go:139。

我发现这是通过runtime.Caller()实现的,而所有Golang日志库都会有runtime.Caller()这个调用。我以为找到了最终答案,然后写代码试了下,结果完全正确!但后来发现,在Linux上运行时,它会打印出Windows的路径,这让我很失望。

我意识到,既然go run时可以通过runtime.Caller()获取到正确的结果,go build时也可以通过os.Executable()来获取到正确的路径;那如果我能判定当前程序是通过go run还是go build执行的,选择不同的路径获取方法,所有问题不就迎刃而解了吗。

Go没有提供接口来区分程序是go run还是go build执行,但我们可以根据go run的执行原理来判断。我们可以直接在程序中对比os.Executable()获取到的路径是否与环境变量TEMP设置的路径相同,如果相同,说明是通过go run启动的,因为当前执行路径是在TEMP目录;不同的话自然是go build的启动方式。

下面是完整代码:

在windows执行

在windows编译后上传到Linux执行

对比结果,我们可以看到,在不同的系统中,不同的执行方式,我们封装的getCurrentAbPath方法最终都输出的正确的结果,perfect!
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦见穿堂风 没有爱情我们一样会快乐的对吗 没有爱情的人会快乐么? 解除合同的效力有什么 合同解除会产生什么法律效力 合同解除后,哪些条款仍具效力? 合同解除产生哪些效力呢 民法典中合同解除产生哪些效力 解除合同的效力有哪些 济南七中学校怎么样 【Golang源码分析】Golang如何实现自举(一) Go语言程序编译注入版本信息,提升Debug速度! GHOST对拷硬盘,高手进! 新买的硬盘 用Ghost分区对分区克隆数据时会出现以下问题么? 逸动蓝鲸版1.4t真实油耗是多少 苹果iPhone 5C屏幕图案在哪? 森源河南森源电气集团 西夏区西夏区-主要产业 西夏区西夏区-城市建设 厦门社保卡补办要多久? 宜宾十大最好玩的景点 宜宾好玩的地方排行榜 宜宾哪里好耍 给推荐一下宜宾好玩的地方,我想去宜宾旅游了~ 宜宾有什么好玩的地方大神们帮帮忙 站票坐火车行李有一个行李箱挺重的,我是女生,拿不到行李架上箱子大概高... 17图库应用商店怎么没有了? 17APP怎么在apple store找不到了 17APP被下架了吗 我的qq好吗4开头算不算带4呀不好吗 云顶之弈新手入门详细攻略 云顶之弈怎么玩才能吃鸡 云顶之弈新手怎么玩 怎么对容器中的 Golang 程序打断点Debug? 缩减Golang编译后文件大小的三种方法 golang包管理之vendor 经常吃夜宵会长胖吗 吃夜宵可以长胖吗 皮鞋太大了怎么办? 鞋松爱掉怎么办 怎么样抢红包更快 怎样抢红包最快最多 泉州户口如何迁入厦门?我想在厦门买房落户,没在 厦门呆过!我有个孩子... 辟邪平时戴什么好辟邪平时戴啥好 无法证明资金来源可以定罪吗 强制开通微粒贷可信吗?是真的吗? iphone7手机如何分屏多任务? 抖音蹦蹦蹦那个什么歌抖音蹦蹦蹦蹦蹦英文歌是什么 去深圳红树林哪个地铁出口 青岛市黄岛区红树林珊瑚在哪个地铁站 自己做饭要买哪些东西 自己动手做饭需要做好哪些准备? 炒股十年,通过简单的均线战法实现稳定盈利!