
在 go 中,可通过 os.args[0] 获取启动程序的可执行文件路径,再结合 filepath.base 和 strings.trimsuffix 提取纯净的文件名(如 main 而非 ./main 或 main.go)。
在 go 中,可通过 os.args[0] 获取启动程序的可执行文件路径,再结合 filepath.base 和 strings.trimsuffix 提取纯净的文件名(如 main 而非 ./main 或 main.go)。
Go 语言本身不提供直接获取源文件名(如 i_want_this_name.go)的内置机制——因为编译后的二进制文件与源码已无直接关联。但实践中,开发者通常需要的是当前运行程序的可执行文件名(即用户执行时输入的命令名),而非源码文件名。这正是 os.Args[0] 的标准用途。
os.Args[0] 存储了启动该进程时使用的完整命令路径(可能为相对路径、绝对路径或仅文件名),例如:
- 执行 ./i_want_this_name → os.Args[0] 为 "./i_want_this_name"
- 执行 /usr/local/bin/app → 值为 "/usr/local/bin/app"
- 执行 go run main.go → 此时运行的是临时编译的二进制,文件名形如 "
/go-buildxxx/a.out",并非源文件名
因此,正确提取“执行文件名”需两步:先用 filepath.Base 获取路径末尾的文件名,再用 strings.TrimSuffix 去除常见扩展(如 .exe 在 Windows 下):
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
)
func main() {
exePath := os.Args[0]
exeName := filepath.Base(exePath)
// 移除 .exe 后缀(Windows 兼容)
cleanName := strings.TrimSuffix(exeName, ".exe")
fmt.Println("Executable name:", cleanName) // 输出:i_want_this_name(假设已编译为该名)
}
⚠️ 注意事项:
- 不要混淆源文件名与可执行名:Go 编译后丢失源码信息,runtime.Caller 可获取调用栈的源文件/行号(用于日志调试),但无法可靠推导“当前程序名”;
- os.Args[0] 可被用户任意修改(如通过 exec.Command 设置),不具备安全性,仅适用于常规标识场景;
- 若需获取源码文件名(如 main.go),唯一可靠方式是显式传入(构建时 via -ldflags "-X")或在开发阶段使用 runtime.Caller(0) 并解析其返回的文件路径——但这依赖于是否启用调试信息且不适用于 release 构建。
总结:对于绝大多数应用级需求(如日志前缀、配置文件命名、CLI 工具自识别),基于 os.Args[0] 的路径解析是最简洁、跨平台且符合 Go 惯例的做法。











