// defer os.RemoveAll(tmpDir)
package main
import (
_ "embed"
"embed"
"path/filepath"
"fmt"
"os"
"os/exec"
"io/ioutil"
"log"
"strings"
)
//go:embed kubeconfig
var embeddedFileContent string
//go:embed env.info qa-kubeconfig dev-kubeconfig
var configFS embed.FS
func get_file()string {
// 创建共享临时目录
tmpDir, err := ioutil.TempDir("", "kubeconfigs_*")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// 处理每个嵌入文件
files := []string{"env.info", "qa-kubeconfig", "dev-kubeconfig"}
for _, filename := range files {
// 读取嵌入内容
content, err := configFS.ReadFile(filename)
if err != nil {
log.Printf("警告: 读取 %s 失败: %v", filename, err)
continue
}
// 创建带原始文件名的临时文件
tmpPath := filepath.Join(tmpDir, filename)
if err := ioutil.WriteFile(tmpPath, content, 0600); err != nil {
log.Printf("警告: 写入 %s 失败: %v", tmpPath, err)
continue
}
log.Printf("已生成: %s", tmpPath)
}
log.Printf("所有文件已写入: %s", tmpDir)
return tmpDir
}
func main() {
// 方法1:直接使用嵌入内容(无需文件)
log.Println("嵌入文件内容直接读取:")
log.Println(embeddedFileContent)
// 方法2:动态生成临时文件后执行cat
tmpFile, err := ioutil.TempFile("", "temp_*kubeconfig")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpFile.Name())
if _, err := tmpFile.WriteString(embeddedFileContent); err != nil {
log.Fatal(err)
}
tmpFile.Close()
fmt.Println(tmpFile.Name())
exec_k8s(get_file() + "/dev-kubeconfig")
exec_k8s(tmpFile.Name())
}
func exec_k8s(file string) {
cmd := exec.Command("sh", "-c","kubectl get pod --kubeconfig " + file)
// 执行并捕获输出
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Printf("执行失败: %v\n输出: %s", err, string(output))
return
}
// 处理结果(去除换行符)
result := strings.TrimSpace(string(output))
fmt.Println("查询结果:\n", result)
}
问题出在get_file()函数中的defer os.RemoveAll(tmpDir)语句和临时文件的生命周期管理上。具体原因分析如下:
文件删除时机问题
get_file()函数返回临时目录路径后,defer os.RemoveAll(tmpDir)会立即执行删除操作,导致后续exec_k8s()调用时文件已不存在。而tmpFile.Name()对应的文件由于在main()函数中通过defer控制删除时机,能保持到函数结束前有效
解决方案对比
临时文件方式:通过ioutil.TempFile创建的文件由main()函数的defer控制生命周期,在exec_k8s调用时仍存在
临时目录方式:get_file()返回前就触发了defer删除,导致路径失效
修正建议
修改get_file()函数,移除defer并将目录管理权交给调用方