命令行编程

使用os.Args获取命令行参数

os.Args切片存储了命令行的所有参数,其中首位元素为命令名称:

package main

import (
    "fmt"
    "os"
)

func main() {
    s, sep := "", ""
    for _, arg := range os.Args { // 通常使用方式:args := os.Args[1:]
        s += sep + arg
        sep = " "
    }
    fmt.Println(s)
}

构建完毕后,执行可执行程序main: ./main a bcd edf结果如下

~/GlandProject/bin/main a bcd edf

使用flag获取命令行参数

package main

import "flag"
import "fmt"

// 定义命令行参数对应的变量,这三个变量都是指针类型
// 参数1代表命令行参数名称
// 参数2代表命令行参数默认值
// 参数3代表输入help命令的提示
var cliName = flag.String("name", "nick", "Input Your Name")
var cliAge = flag.Int("age", 28, "Input Your Age")
var cliGender = flag.String("gender", "male", "Input Your Gender")

// 定义一个值类型的命令行参数变量,在 Init() 函数中对其初始化
// 因此,命令行参数对应变量的定义和初始化是可以分开的
var cliFlag int
func init() {
    flag.IntVar(&cliFlag, "flagname", 1234, "Just for demo")
}

func main() {
    // 把用户传递的命令行参数解析为对应变量的值
    flag.Parse()

    // flag.Args() 函数返回没有被解析的命令行参数
    // func NArg() 函数返回没有被解析的命令行参数的个数
    fmt.Printf("args=%s, num=%d\n", flag.Args(), flag.NArg())
    for i := 0; i != flag.NArg(); i++ {
        fmt.Printf("arg[%d]=%s\n", i, flag.Arg(i))
    }

    // 输出命令行参数
    fmt.Println("name=", *cliName)
    fmt.Println("age=", *cliAge)
    fmt.Println("gender=", *cliGender)
    fmt.Println("flagname=", cliFlag)
}

无任何输入参数调用:

$ ./main        
args=[], num=0
name= nick
age= 28
gender= male
flagname= 1234

传递参数调用:

$ ./main -name=zhangsan -age=18 -gender=人妖  
args=[], num=0
name= zhangsan
age= 18
gender= 人妖
flagname= 1234

传递错误的参数:

$ ./main -hobby=study             # 没有hobby参数            
flag provided but not defined: -hobby
Usage of ./main:
  -age int
        Input Your Age (default 28)
  -flagname int
        Just for demo (default 1234)
  -gender string
        Input Your Gender (default "male")
  -name string
        Input Your Name (default "nick")

传递多余的参数调用:

$ ./main -name=李四 a bc
args=[a bc], num=2 # 这是多余的参数,多余参数不能是 -xxx 或者 --xxx的形式
arg[0]=a
arg[1]=bc
name= 李四
age= 28
gender= male
flagname= 1234

查看帮助命令

flag会自动为程序生成帮助命令:

$ ./main --help       # 或者使用 -h
Usage of ./main:
  -age int
        Input Your Age (default 28)
  -flagname int
        Just for demo (default 1234)
  -gender string
        Input Your Gender (default "male")
  -name string
        Input Your Name (default "nick")

命令行传参形式

  • 单个bool标志:main -b=true,可以省略为main -b

  • 一下四种传参形式是相同的:

    • main --name=zhangsa

    • main --name zhangsan

    • main -name=zhangsan

    • main -name zhangsan

  • 约定俗称将单个-表示命令参数的缩写,两个-,也就是--表示命令参数全写

非标志参数

也就是不带-的参数:

flag.Args()

命令缩写实现

通过提供2个标志处理程序实现:

var gopherType string

func init() {
    const (
        defaultGopher = "pocket"
        usage         = "the variety of gopher"
    )
    flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
    flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)")
}

强制参数

也就是必需参数,通过判断值是否为零值确认:

// [...]
flag.Parse()

if *count == "" {
    flag.PrintDefaults()
    os.Exit(1) // 以代码1退出
}

最后更新于