How to provide the command line args first and then the flags in golang?

huangapple go评论76阅读模式
英文:

How to provide the command line args first and then the flags in golang?

问题

Golang的flag包可以正确读取命令行标志和参数,如果输入的形式是:go run main.go -o filename.txt arg1 arg2

但是,如果我尝试以以下方式提供输入:go run main.go arg1 arg2 -o filename.txt,则main.go之后的所有内容都被读取为参数。

如何使这种样式工作?

我的程序:

package main

import (
	"flag"
	"fmt"
)

func main() {

	var output string
	flag.StringVar(&output, "o", "", "Writes output to the file specified")
	flag.Parse()
	fmt.Println("Positional Args : ", flag.Args())
	fmt.Println("Flag -o : ", output)
}

go run main.go -o filename.txt arg1 arg2

输出:

Positional Args :  [arg1 arg2]
Flag -o :  filename.txt

go run main.go arg1 arg2 -o filename.txt

输出:

Positional Args :  [arg1 arg2 -o filename.txt]
Flag -o :
英文:

Golang's flag package reads the command line flags and args properly if the input provided is of the form : go run main.go -o filename.txt arg1 arg2

But if I try to provide the input like : go run main.go arg1 arg2 -o filename.txt, everything after main.go is read as arguments.

How to make this style work?

My program:

package main

import (
	"flag"
	"fmt"
)

func main() {

	var output string
	flag.StringVar(&output, "o", "", "Writes output to the file specified")
	flag.Parse()
	fmt.Println("Positional Args : ", flag.Args())
	fmt.Println("Flag -o : ", output)
}

go run main.go -o filename.txt arg1 arg2

Output:

Positional Args :  [arg1 arg2]
Flag -o :  filename.txt

go run main.go arg1 arg2 -o filename.txt

Output:

Positional Args :  [arg1 arg2 -o filename.txt]
Flag -o :

答案1

得分: 3

如果你在os.Args的内容上进行调整,就可以接受"arg1 arg2 -o filename.txt"的输入。

在for循环中遍历从命令行传入的os.Args。

如果遇到一个"-",则设置一个条件来指示已经看到了第一个标志。

如果条件被设置,则填充"notargs"列表。否则,填充"args"列表。

这里有一点额外的复杂性,因为用于设置os.Args的args列表必须包括程序名称(原始的os.Arg[0])作为第一个值。

这个解决方案不适用于"-o filename.txt arg1 arg2"的情况。

package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {

    var output string
    var args []string
    var notargs []string
    var in_flags bool = false
    for i := 0; i < len(os.Args); i++ {
        if os.Args[i][0] == '-' {
            in_flags = true
        }
        if i == 0 || in_flags {
            notargs = append(notargs, os.Args[i])
        } else {
            args = append(args, os.Args[i])
        }
    }
    os.Args = notargs
    flag.StringVar(&output, "o", "", "Writes output to the file specified")
    flag.Parse()
    fmt.Println("args ", args)
    fmt.Println("Flag -o : ", output)
}
英文:

If you shimmy around with the contents of os.Args, it is possible to accept arg1 arg2 -o filename.txt

Go through the os.Args that is passed in from the command line in the for loop

If a - is seen then set a condition that indicates the first flag has been seen

If the condition is set then populate the "notargs" list. Otherwise, populate the "args" list

There is a bit of extra complication here as the args list that is used to set os.Args to the values that will do the flag processing must include the program name (the original os.Arg[0]) as the first value

This solution does not work with -o filename.txt arg1 arg2

package main

import (
    &quot;flag&quot;
    &quot;fmt&quot;
    &quot;os&quot;
)

func main() {

    var output string
    var args[]string
    var notargs[]string
    var in_flags bool=false
    for i:=0; i&lt;len(os.Args); i++ {
      if os.Args[i][0]==&#39;-&#39; {
       in_flags=true
      }
      if i==0 || in_flags {
        notargs=append(notargs,os.Args[i])
      } else {
        args=append(args,os.Args[i])
      }
    }
    os.Args=notargs
    flag.StringVar(&amp;output, &quot;o&quot;, &quot;&quot;, &quot;Writes output to the file specified&quot;)
    flag.Parse()
    fmt.Println(&quot;args &quot;,args)
    fmt.Println(&quot;Flag -o : &quot;, output)
}

huangapple
  • 本文由 发表于 2021年11月27日 18:08:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/70133798.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定