Go provides the flag package supporting basic command-line flag parsing. We’ll use this package to implement our example command-line program.
Golang Flag
Golang flag package implements command-line flag parsing. Command-line flags are the common way to specify options for command-line programs. We can define flags using flag.String(), flag.Bool(), flag.Int(), etc.
This declares the integer flag, -flagname, stored in the pointer ip, with type *int.
Add import “flag” to the import section of your package, and it’s ready to use.
The flag provides many functions to parse different flag types, and you’ll need to use the different ones for each type you want to accept:
func Bool(name string, value bool, data string) *bool func BoolVar(p *bool, name string, value bool, data string) func Duration(name string, value time.Duration, data string) *time.Duration func DurationVar(p *time.Duration, name string, value time.Duration, data string) func Float64(name string, value float64, data string) *float64 func Float64Var(p *float64, name string, value float64, data string) func Int(name string, value int, data string) *int func Int64(name string, value int64, data string) *int64 func Int64Var(p *int64, name string, value int64, data string) func IntVar(p *int, name string, value int, data string) func String(name string, value string, data string) *string func StringVar(p *string, name string, value string, data string) func Uint(name string, value uint, data string) *uint func Uint64(name string, value uint64, data string) *uint64 func Uint64Var(p *uint64, name string, value uint64, data string) func UintVar(p *uint, name string, value uint, data string)
Passing the wrong type for a flag will raise an error, halt the program, and the required usage will be printed to the user.
Let’s see the main three functions in detail.
Golang flag.int()
See the following code.
// hello.go package main import ( "flag" "fmt" ) func main() { ip := flag.Int("num", 111921, "Mandalorian Episode 4") fmt.Println("Number", *ip) }
Output
➜ go run hello.go Number 111921
Here we declare the int flag word with a default value “111921” and a short description. This flag.Int() the function returns an integer pointer (not a string value).
If you like, you can bind a flag to the variable using the Var() functions.
See the following code.
// hello.go package main import ( "flag" "fmt" ) func main() { var flagvar int flag.IntVar(&flagvar, "flagvar", 111921, "Mandalorian Episode 4") fmt.Println("Number", flagvar) }
Output
➜ go run hello.go Number 111921
In the above code, the default value of the flag variable is just the initial value of the variable.
Golang flag.string()
Let’s see the code for a String variable.
// hello.go package main import ( "flag" "fmt" ) func main() { var flagvar string flag.StringVar(&flagvar, "flagvar", "Gina Carano", "Mandalorian Episode 4") fmt.Println("Name", flagvar) }
Output
go run hello.go Name Gina Carano
Golang flag.boolean()
See the following code.
// hello.go package main import ( "flag" "fmt" ) func main() { var flagvar bool flag.BoolVar(&flagvar, "flagvar", true, "Mandalorian Episode 4") fmt.Println("Boolean Value", flagvar) }
Output
➜ go run hello.go Boolean Value true
Now, let’s combine all three in one program.
// hello.go package main import ( "flag" "fmt" ) func main() { var flagvar int var flagvar2 string var flagvar3 bool flag.IntVar(&flagvar, "flagvar", 111921, "Mandalorian Episode 4") flag.StringVar(&flagvar2, "flagvar2", "Gina Carano", "Mandalorian Episode") flag.BoolVar(&flagvar3, "flagvar3", true, "Mandalorian") fmt.Println("Integer Value", flagvar) fmt.Println("String Value", flagvar2) fmt.Println("Boolean Value", flagvar3) }
Output
go run hello.go Integer Value 111921 String Value Gina Carano Boolean Value true
flag.parse()
After all flags are defined, call flag.parse() method.
// hello.go package main import ( "flag" "fmt" ) func main() { var flagvar int var flagvar2 string var flagvar3 bool flag.IntVar(&flagvar, "flagvar", 111921, "Mandalorian Episode 4") flag.StringVar(&flagvar2, "flagvar2", "Gina Carano", "Mandalorian Episode") flag.BoolVar(&flagvar3, "flagvar3", true, "Mandalorian") flag.Parse() fmt.Println("flagvar:", flagvar) fmt.Println("flagvar2:", flagvar2) fmt.Println("flagvar3:", flagvar3) }
After parsing, the arguments following the flags are available as a slice flag.Args() or individually as the flag.Arg(i).
The arguments are indexed from 0 through flag.NArg()-1.
To experiment with the command-line flags program, it’s best to compile it and then run the resulting binary directly.
See the following output.
➜ go build hello.go ➜ ./hello -flagvar=21 -flagvar2=AppDividend -flagvar3=false flagvar: 21 flagvar2: AppDividend flagvar3: false
From the above output, you can see that our command-line arguments’ value overrides the flag’s initial values.
Command-line flag syntax in Golang
The following forms are permitted.
-flag -flag=x -flag x
One or two minus signs may be used; they are equivalent.
The last form is not permitted for boolean flags because of the meaning of the command.
cmd -x *
Where * is the Unix shell wildcard, will change if the file is called 0, false, etc. You must use the -flag=false form to turn off a boolean flag.
You can pass as many flags as you want to the command, but the first time the flag does not recognize it, it will stop parsing the additional ones. This means that flags must all go at the beginning if you have non-flag parameters, as well.
Flag parsing stops just before the first non-flag argument (“-” is a non-flag argument) or after the terminator “–“.
Integer flags accept the numbers 1234, 0664, 0x1234 and may be negative. Boolean flags may be:
1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
Duration flags take any input valid for time.ParseDuration.
Top-level functions control the default set of command-line flags.
The FlagSet type allows one to define independent sets of flags, such as implementing subcommands in a command-line interface.
The methods of FlagSet are analogous to the top-level functions for the command-line flag set.
Parsing non-flag parameters
The flag package provides methods also to parse non-flag parameters.
flag.Args()
It returns a slice of strings with the parameters not parsed as flags.
Conclusion
There are many ways to process CLI flags using Go. The first option is not to inspect os.Args.
The second option which we have seen is to use the standard library flag package.
The third option is to use one of the many 3rd party CLI libs out there, like Cobra.