diff --git a/examples.txt b/examples.txt index 9e13b51..2c1539b 100644 --- a/examples.txt +++ b/examples.txt @@ -59,6 +59,7 @@ Writing Files Line Filters Command-Line Arguments Command-Line Flags +Command-Line Subcommands Environment Variables HTTP Clients Spawning Processes diff --git a/examples/command-line-subcommands/command-line-subcommands.go b/examples/command-line-subcommands/command-line-subcommands.go new file mode 100644 index 0000000..132c9ec --- /dev/null +++ b/examples/command-line-subcommands/command-line-subcommands.go @@ -0,0 +1,57 @@ +// Some command-line tools, like the `go` tool or `git` +// have many *subcommands*, each with its own set of +// flags. For example, `go build` and `go get` are two +// different subcommands of the `go` tool. +// The `flag` package lets us easily define simple +// subcommands that have their own flags. + +package main + +import ( + "flag" + "fmt" + "os" +) + +func main() { + + // We declare a subcommand using the `NewFlagSet` + // function, and proceed to define new flags specific + // for this subcommand. + fooCmd := flag.NewFlagSet("foo", flag.ExitOnError) + fooEnable := fooCmd.Bool("enable", false, "enable") + fooName := fooCmd.String("name", "", "name") + + // For a different subcommand we can define different + // supported flags. + barCmd := flag.NewFlagSet("bar", flag.ExitOnError) + barLevel := barCmd.Int("level", 0, "level") + + // The subcommand is expected as the first argument + // to the program. + if len(os.Args) < 2 { + fmt.Println("expected 'foo' or 'bar' subcommands") + os.Exit(1) + } + + // Check which subcommand is invoked. + switch os.Args[1] { + case "foo": + + // For every subcommand, we parse its own flags and + // have access to trailing positional arguments. + fooCmd.Parse(os.Args[2:]) + fmt.Println("subcommand 'foo'") + fmt.Println(" enable:", *fooEnable) + fmt.Println(" name:", *fooName) + fmt.Println(" tail:", fooCmd.Args()) + case "bar": + barCmd.Parse(os.Args[2:]) + fmt.Println("subcommand 'bar'") + fmt.Println(" level:", *barLevel) + fmt.Println(" tail:", barCmd.Args()) + default: + fmt.Println("expected 'foo' or 'bar' subcommands") + os.Exit(1) + } +} diff --git a/examples/command-line-subcommands/command-line-subcommands.hash b/examples/command-line-subcommands/command-line-subcommands.hash new file mode 100644 index 0000000..b26ba5f --- /dev/null +++ b/examples/command-line-subcommands/command-line-subcommands.hash @@ -0,0 +1,2 @@ +673d7811734cfd8f8f5bcb411e12def1e158cf0b +V7xR3wMkquz diff --git a/examples/command-line-subcommands/command-line-subcommands.sh b/examples/command-line-subcommands/command-line-subcommands.sh new file mode 100644 index 0000000..a7cec9a --- /dev/null +++ b/examples/command-line-subcommands/command-line-subcommands.sh @@ -0,0 +1,21 @@ +$ go build command-line-subcommands.go + +# First invoke the foo subcommand +$ ./command-line-subcommands foo -enable -name=joe a1 a2 +subcommand 'foo' + enable: true + name: joe + tail: [a1 a2] + +# Now try bar +$ ./command-line-subcommands bar -level 8 a1 +subcommand 'bar' + level: 8 + tail: [a1] + +# But bar won't accept foo's flags +$ ./command-line-subcommands bar -enable a1 +flag provided but not defined: -enable +Usage of bar: + -level int + level diff --git a/public/command-line-flags b/public/command-line-flags index 47341d4..b2eb253 100644 --- a/public/command-line-flags +++ b/public/command-line-flags @@ -297,7 +297,7 @@ way to parameterize programs.

- Next example: Environment Variables. + Next example: Command-Line Subcommands.

+

Go by Example: Command-Line Subcommands

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Some command-line tools, like the go tool or git +have many subcommands, each with its own set of +flags. For example, go build and go get are two +different subcommands of the go tool. +The flag package lets us easily define simple +subcommands that have their own flags.

+ +
+ + +
+ + + +
package main
+
+ +
+ + + +
import (
+    "flag"
+    "fmt"
+    "os"
+)
+
+ +
+ + + +
func main() {
+
+ +
+

We declare a subcommand using the NewFlagSet +function, and proceed to define new flags specific +for this subcommand.

+ +
+ +
    fooCmd := flag.NewFlagSet("foo", flag.ExitOnError)
+    fooEnable := fooCmd.Bool("enable", false, "enable")
+    fooName := fooCmd.String("name", "", "name")
+
+ +
+

For a different subcommand we can define different +supported flags.

+ +
+ +
    barCmd := flag.NewFlagSet("bar", flag.ExitOnError)
+    barLevel := barCmd.Int("level", 0, "level")
+
+ +
+

The subcommand is expected as the first argument +to the program.

+ +
+ +
    if len(os.Args) < 2 {
+        fmt.Println("expected 'foo' or 'bar' subcommands")
+        os.Exit(1)
+    }
+
+ +
+

Check which subcommand is invoked.

+ +
+ +
    switch os.Args[1] {
+    case "foo":
+
+ +
+

For every subcommand, we parse its own flags and +have access to trailing positional arguments.

+ +
+ +
        fooCmd.Parse(os.Args[2:])
+        fmt.Println("subcommand 'foo'")
+        fmt.Println("  enable:", *fooEnable)
+        fmt.Println("  name:", *fooName)
+        fmt.Println("  tail:", fooCmd.Args())
+    case "bar":
+        barCmd.Parse(os.Args[2:])
+        fmt.Println("subcommand 'bar'")
+        fmt.Println("  level:", *barLevel)
+        fmt.Println("  tail:", barCmd.Args())
+    default:
+        fmt.Println("expected 'foo' or 'bar' subcommands")
+        os.Exit(1)
+    }
+}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
$ go build command-line-subcommands.go 
+
+ +
+

First invoke the foo subcommand

+ +
+ +
$ ./command-line-subcommands foo -enable -name=joe a1 a2
+subcommand 'foo'
+  enable: true
+  name: joe
+  tail: [a1 a2]
+
+ +
+

Now try bar

+ +
+ +
$ ./command-line-subcommands bar -level 8 a1
+subcommand 'bar'
+  level: 8
+  tail: [a1]
+
+ +
+

But bar won’t accept foo’s flags

+ +
+ +
$ ./command-line-subcommands bar -enable a1
+flag provided but not defined: -enable
+Usage of bar:
+  -level int
+    	bar level
+
+ +
+ + +

+ Next example: Environment Variables. +

+ + +
+ + diff --git a/public/index.html b/public/index.html index 6b5727f..ca79490 100644 --- a/public/index.html +++ b/public/index.html @@ -145,6 +145,8 @@
  • Command-Line Flags
  • +
  • Command-Line Subcommands
  • +
  • Environment Variables
  • HTTP Clients