golang命令行参数解析插件库getopt的使用

golang命令行参数解析插件库getopt的使用

简介

getopt包提供了一个零依赖的Go实现,用于解析Unix风格的命令行选项。它支持POSIX约定,包括短选项(如-a)和选项参数,同时也支持GNU扩展,如长选项(如--option)、可选参数和重新排列非选项参数。

安装

go get github.com/jonathonwebb/getopt

使用示例

基本用法

package main

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

func main() {
	// 创建新的解析状态
	state := getopt.NewState(os.Args)
	
	// 配置选项字符串:
	// a - 无参数选项
	// b: - 必须带参数的选项
	// c:: - 可选参数的选项
	config := getopt.Config{Opts: getopt.OptStr(`ab:c::`)}
	
	// 解析所有选项
	opts, err := state.Parse(config)
	if err != nil {
		fmt.Printf("Error parsing options: %v\n", err)
		return
	}
	
	// 处理解析结果
	for _, opt := range opts {
		switch opt.Char {
		case 'a':
			fmt.Println("Found option a")
		case 'b':
			fmt.Printf("Found option b with argument: %s\n", opt.OptArg)
		case 'c':
			if opt.OptArg != "" {
				fmt.Printf("Found option c with argument: %s\n", opt.OptArg)
			} else {
				fmt.Println("Found option c without argument")
			}
		}
	}
}

迭代式解析

package main

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

func main() {
	state := getopt.NewState(os.Args)
	config := getopt.Config{Opts: getopt.OptStr(`ab:c::`)}

	// 逐个解析选项
	for opt, err := range state.All(config) {
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			break
		}
		
		switch opt.Char {
		case 'a':
			fmt.Println("Found option a")
		case 'b':
			fmt.Printf("Found option b with argument: %s\n", opt.OptArg)
		case 'c':
			if opt.OptArg != "" {
				fmt.Printf("Found option c with argument: %s\n", opt.OptArg)
			} else {
				fmt.Println("Found option c without argument")
			}
		}
	}
}

行为模式

getopt支持多种解析模式:

  • ModeGNU: 启用默认行为(GNU风格)
  • ModePosix: 启用POSIX兼容模式,禁用参数重新排列并在第一个非选项参数处停止解析
  • ModeInOrder: 按顺序处理所有参数

功能选项

可以配置不同的解析函数:

  • FuncGetOpt: 仅解析传统的POSIX短选项(如-a)
  • FuncGetOptLong: 解析短选项和GNU扩展的长选项(如--option)
  • FuncGetOptLongOnly: 解析短选项和长选项,但允许长选项以单破折号开头

注意事项

与GNU libc的getopt相比,此包有以下不同:

  1. 接受短选项和长选项定义中的多字节字符
  2. 不实现与GNU libc完全相同的参数重新排列

完整示例

下面是一个完整的示例,展示如何使用getopt解析命令行参数:

package main

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

func main() {
	// 定义长选项
	longOpts := []getopt.LongOpt{
		{Name: "help", HasArg: getopt.NoArgument, Val: 'h'},
		{Name: "version", HasArg: getopt.NoArgument, Val: 'v'},
		{Name: "output", HasArg: getopt.RequiredArgument, Val: 'o'},
		{Name: "verbose", HasArg: getopt.OptionalArgument, Val: 'V'},
	}

	// 创建解析状态
	state := getopt.NewState(os.Args)
	
	// 配置解析选项
	config := getopt.Config{
		Opts:    getopt.OptStr("hvo::V::"), // 短选项
		LongOpt: longOpts,                  // 长选项
		Mode:    getopt.ModeGNU,            // GNU模式
		Func:    getopt.FuncGetOptLong,     // 启用长选项解析
	}

	// 解析选项
	for opt, err := range state.All(config) {
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			continue
		}

		switch opt.Char {
		case 'h':
			fmt.Println("Help message")
		case 'v':
			fmt.Println("Version 1.0.0")
		case 'o':
			fmt.Printf("Output file: %s\n", opt.OptArg)
		case 'V':
			if opt.OptArg != "" {
				fmt.Printf("Verbose level: %s\n", opt.OptArg)
			} else {
				fmt.Println("Verbose mode enabled")
			}
		default:
			fmt.Printf("Unknown option: %c\n", opt.Char)
		}
	}

	// 处理剩余的非选项参数
	args := state.Args()
	if len(args) > 0 {
		fmt.Println("Non-option arguments:")
		for _, arg := range args {
			fmt.Printf("- %s\n", arg)
		}
	}
}

这个示例展示了如何同时使用短选项和长选项,并处理可选和必需的参数。


更多关于golang命令行参数解析插件库getopt的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang命令行参数解析插件库getopt的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang命令行参数解析:getopt库使用指南

getopt是Go语言中一个流行的命令行参数解析库,它模仿了Unix/Linux系统中传统的getopt函数行为,提供了简单易用的命令行参数解析功能。

安装getopt

go get github.com/pborman/getopt

基本使用方法

1. 定义参数

package main

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

func main() {
	// 定义参数
	helpFlag := getopt.Bool('h', "display help")  // -h 或 --help
	name := getopt.String('n', "", "your name")   // -n 或 --name
	age := getopt.Int('a', 0, "your age")         // -a 或 --age
	verbose := getopt.BoolLong("verbose", 'v', "verbose output") // --verbose 或 -v

	// 解析命令行参数
	getopt.Parse()
	
	// 处理帮助信息
	if *helpFlag {
		getopt.Usage()
		return
	}
	
	// 使用参数
	fmt.Printf("Hello %s, age %d\n", *name, *age)
	if *verbose {
		fmt.Println("Verbose mode enabled")
	}
}

2. 参数类型

getopt支持多种参数类型:

  • Bool/BoolLong: 布尔标志
  • String/StringLong: 字符串参数
  • Int/IntLong: 整数参数
  • List/ListLong: 字符串列表参数

3. 参数说明

每个参数定义函数都有类似的签名:

func [Type][Long](short rune, default value, description string) *Type
  • short: 短参数名(单个字符),0表示没有短参数
  • default: 默认值
  • description: 参数描述,会在帮助信息中显示

对于Long版本,第一个参数是长参数名:

func [Type]Long(long string, short rune, default value, description string) *Type

高级用法

1. 必选参数

name := getopt.String('n', "", "your name (required)")
getopt.Parse()

if *name == "" {
	fmt.Println("Name is required")
	getopt.Usage()
	os.Exit(1)
}

2. 位置参数

func main() {
	// 定义标志参数
	helpFlag := getopt.Bool('h', "display help")
	
	// 解析标志参数
	getopt.Parse()
	
	// 获取位置参数
	args := getopt.Args()
	
	if *helpFlag || len(args) == 0 {
		getopt.Usage()
		return
	}
	
	fmt.Println("Positional arguments:", args)
}

3. 自定义帮助信息

func main() {
	// 设置程序名和自定义用法信息
	getopt.SetProgram("myprogram")
	getopt.SetUsage(func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", getopt.Program())
		getopt.PrintUsage(os.Stderr)
		fmt.Fprintf(os.Stderr, "\nExamples:\n")
		fmt.Fprintf(os.Stderr, "  %s -n John -a 30\n", getopt.Program())
	})
	
	// 参数定义...
}

完整示例

package main

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

func main() {
	// 设置程序信息
	getopt.SetProgram("greeter")
	getopt.SetUsage(func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", getopt.Program())
		getopt.PrintUsage(os.Stderr)
		fmt.Fprintln(os.Stderr, "\nA simple program that greets you")
	})

	// 定义参数
	helpFlag := getopt.Bool('h', "display help")
	name := getopt.StringLong("name", 'n', "", "your name (required)")
	age := getopt.IntLong("age", 'a', 0, "your age")
	verbose := getopt.BoolLong("verbose", 'v', "verbose output")
	times := getopt.IntLong("times", 't', 1, "number of times to greet")

	// 解析参数
	getopt.Parse()

	// 处理帮助
	if *helpFlag {
		getopt.Usage()
		return
	}

	// 验证必选参数
	if *name == "" {
		fmt.Fprintln(os.Stderr, "Error: name is required")
		getopt.Usage()
		os.Exit(1)
	}

	// 使用参数
	for i := 0; i < *times; i++ {
		fmt.Printf("Hello %s", *name)
		if *age > 0 {
			fmt.Printf(", age %d", *age)
		}
		fmt.Println()

		if *verbose {
			fmt.Printf("Greeting #%d completed\n", i+1)
		}
	}
}

总结

getopt库提供了简单直观的命令行参数解析功能,适合大多数命令行程序的需求。它的主要特点包括:

  1. 支持短参数(-h)和长参数(–help)
  2. 自动生成帮助信息
  3. 支持多种参数类型
  4. 简单易用的API

对于更复杂的命令行应用,可以考虑使用标准库的flag包或更强大的第三方库如cobra,但对于大多数简单到中等复杂度的命令行程序,getopt已经足够使用。

回到顶部