Ben Chuanlong Du's Blog

It is never too late to learn.

Parse Command Line Arguments Using Flag in Go

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

It is suggested that you use the Golang module spf13/cobra (instead of the standard Golang library flag) for parsing command-line arguments.

In [1]:
import (
    "flag"
    "fmt"
)

Declare a string flag --name with a default value "Ben" and a short description. Notice that the function flag.String returns a string pointer (not a string value).

In [2]:
wordPtr := flag.String("name", "Ben", "Name of a person.")
In [3]:
numbPtr := flag.Int("numb", 42, "an int")
forkPtr := flag.Bool("fork", false, "a bool")
In [4]:
flag.Parse()
In [5]:
*wordPtr
Out[5]:
Ben
In [6]:
*numbPtr
Out[6]:
42
In [7]:
*forkPtr
Out[7]:
false
In [8]:
flag.Args()
Out[8]:
[/home/dclong/.local/share/jupyter/runtime/kernel-9d64ca68-de95-4d2c-a5a1-256edc785832.json]

Sub Commands

You can define sub-commands using flag.NewFlagSet. However, flag does not automatically generate help docs for sub-commands defined (which is not as convenient as argparse in Python). One way to improve the default behavior here is to overwrite the -h option for the main command and print help documentation on sub-commands when -h is specified. Below is such an example.

In [1]:
package main

import "flag"
import "fmt"
import "os"

func main() {
	help := flag.Bool("h", false, "show help doc")
	fooCmd := flag.NewFlagSet("foo", flag.ExitOnError)
	barCmd := flag.NewFlagSet("bar", flag.ExitOnError)
	flag.Parse()
	if *help {
		fmt.Printf(`Usage of %s
    foo - help doc on foo
    bar - help doc on bar
`, os.Args[0])
		os.Exit(0)
	}
	switch os.Args[1] {
		case "foo": _parse_foo(fooCmd)
		case "bar": _parse_bar(barCmd)
	}
}

func _parse_foo(fooCmd *flag.FlagSet) {
	fooEnable := fooCmd.Bool("enable", false, "enable")
	fooName := fooCmd.String("name", "", "name")
	fooCmd.Parse(os.Args[2:])
	fmt.Println("subcommand 'foo'")
	fmt.Println("  enable:", *fooEnable)
	fmt.Println("  name:", *fooName)
	fmt.Println("  tail:", fooCmd.Args())
}

func _parse_bar(barCmd *flag.FlagSet) {
	barLevel := barCmd.Int("level", 0, "level")
	barCmd.Parse(os.Args[2:])
	fmt.Println("subcommand 'bar'")
	fmt.Println("  level:", *barLevel)
	fmt.Println("  tail:", barCmd.Args())
}
In [ ]:
 

Comments