John
John

Reputation: 219

Issue with golang flags

So recently I ran into a problem with Golang flags and was curious to know if this is as intended, if its a problem or if I'm being a blithering idiot and there is a very simple answer to this.

So using the following code:

func main() {
    test := flag.String("-test", "", "test var")
    flag.Parse()
    if *test != "" {
        fmt.Println(*test)
    }
}

And then run it using the following command ./main -test 1

You get the following autogenerated error:

flag provided but not defined: -test
Usage of ./main:
  --test string
        test var

The same happens if you then use ./main --test 1, you get the same error. The only way I have found around this is to change the flag definition to be test := flag.String("test", "", "test var") and then run it with ./main -test 1.

So my question is why can you not use double hyphens with flags? If you can, where did I go wrong when doing this?

Upvotes: 4

Views: 7150

Answers (3)

Coconut
Coconut

Reputation: 2222

For us the flag package is probably not the nicest thing to use here.

Instead of that, you might want to try getopt package owned by Google, which provides the more standard command line parsing (vs the flag package).

package main

import (
    "fmt"
    "os"
    "github.com/pborman/getopt"
)

func main() {
    optName := getopt.StringLong("name", 'n', "", "Your name")
    optHelp := getopt.BoolLong("test", 0, "test var")
    getopt.Parse()

    if *optHelp {
        getopt.Usage()
        os.Exit(0)
    }

    fmt.Println("Hello " + *optName + "!")
}

$ ./hello --help
Usage: hello [--test] [-n value] [parameters ...]
     --test        test var
 -n, --name=value  Your name

$ ./hello --name Bob
Hello Bob!

Upvotes: 0

0xbadbeef
0xbadbeef

Reputation: 141

You can use double hyphens and this is documented in the package here:

One or two minus signs may be used; they are equivalent.

Having declared your flags, flag.Parse() will try to remove one or two hyphens from the flags passed and use the remaining characters of each flag to detect whether one has been declared or not. This is done internally by the flag package in parseOne().

Declaring a flag with name -test will literally map it as is, resulting in flag.Parse() internally looking for the name test instead of -test which is the one you actually declared, resulting in the error you see.

Instead, use only the name of the flag when declaring one:

test := flag.String("test", "", "test var")

and you can use this flag with both one (./main -test 1) or two hyphens (./main --test 2).

Upvotes: 7

Eugene Lisitsky
Eugene Lisitsky

Reputation: 12875

Try to define the flag without -:

func main() {
    test := flag.String("test", "", "test var")
    flag.Parse()
    if *test != "" {
        fmt.Println(*test)
    }
}

Upvotes: 4

Related Questions