How To Use Command Line Flags in Golang with Example

Command-line utilities are rarely useful out of the box without additional configuration. Good defaults are important, but useful utilities need to accept configuration from users. On most platforms, command-line utilities accept flags to customize the command’s execution. Flags are key-value delimited strings added after the name of the command. Go lets you craft command-line utilities that accept flags by using the flag package from the standard library. We’ll use this package to implement our example command-line program.

Define flags using flag.String(), Bool(), Int(), etc.

This declares an 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 one 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 first to compile it and then run the resulting binary directly.

See the following output.


➜  go build hello.go
➜  ./hello -flagvar=21 -flagvar2=codequs -flagvar3=false
flagvar: 21
flagvar2: codequs
flagvar3: false

From an 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 there is the file 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 the flag, 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 number 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 to implement 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

You’ve seen that the flag package offers flexible choices to present configuration options to your users. You can choose a few simple flags, or build an extensible suite of sub-commands.

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.

Thanks for reading

#go #golang

How To Use Command Line Flags in Golang with Example
1 Likes53.15 GEEK