Go by Example:命令列子指令

有些命令列工具,例如 go 工具或 git 會有很多的子指令,每個子指令都有一組標誌。例如,go buildgo getgo 工具的兩個不同的子指令。flag 套件讓我們能輕鬆地針對擁有自己標誌的簡單子指令進行定義。

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

我們使用 NewFlagSet 函式宣告子指令,並繼續針對這個子指令定義新的特定標誌。

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

我們可以針對不同的子指令定義不同的支援標誌。

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

子指令預期是程式的第一個參數。

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

檢查已呼叫的子指令。

    switch os.Args[1] {

針對每個子指令,我們會剖析它自己的標誌,並且存取後續的位置參數。

    case "foo":
        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 

先呼叫 foo 子指令。

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

現在嘗試 bar。

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

但是 bar 不會接受 foo 的標誌。

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

接下來我們看看環境變數,這是一般用來設定程式參數的另一種方法。

下一個範例:環境變數