Golang:flag.Arg(0)读取exec.Cmd参数索引偏移问题解决
解决Go中exec.Cmd调用时flag.Arg(0)读取参数不符合预期的问题
问题原因
Go的flag包中,flag.Parse()会自动忽略命令行参数的第一个元素(即程序本身的路径/名称,对应os.Args[0]),flag.Arg(n)返回的是第n+1个非程序名的参数(也就是os.Args[n+1])。
而你在foo应用中使用exec.Cmd时,Args字段的设置不符合规范:exec.Cmd的Args第一个元素必须是被执行程序的路径或名称(对应目标程序的os.Args[0]),后续元素才是传递给目标程序的命令行参数。你当前的c.Args为[1,2,3],这会导致bar应用的os.Args变成["1", "2", "3"],flag.Parse()跳过第一个元素"1",flag.Arg(0)自然读取到的是"2"。
解决方案
修正foo应用中exec.Cmd的Args字段,将被执行程序的路径作为第一个元素,再追加实际要传递的参数:
var stdout, stderr bytes.Buffer cmd := exec.Cmd{ Path: c.Path, // 修正Args:第一个元素是程序路径,后续是实际传递的参数 Args: append([]string{c.Path}, "1", "2", "3"...), Env: c.Env, Stdin: bytes.NewReader(b), Stdout: &stdout, Stderr: &stderr, } if err := cmd.Start(); err != nil { return err }
如果你的参数是动态列表(比如原c.Args是实际要传递的参数),可以直接将程序路径前置:
Args: append([]string{c.Path}, c.Args...),
效果说明
修改后,bar应用的os.Args会变为[c.Path, "1", "2", "3"],flag.Parse()跳过第一个元素(程序路径),flag.Arg(0)就能读取到预期的"1"。
内容的提问来源于stack exchange,提问作者James Franco
相关产品推荐
相关产品推荐

