从零开始:Golang命令行完全指南

发表时间: 2024-06-11 14:45

Command-Line工具,也叫命令行工具,是指通过命令行界面(CLI)进行操作的软件。相比图形界面(GUI),CLI工具更加轻量、快速、可自动化,非常适合程序员日常使用。

入门示例

我们先从一个简单的示例开始。假设我们要开发一个CLI工具,它接收一个名字作为参数,并打印出“Hello, [名字]!”

主程序

    name := flag.String("name", "World", "a name to say hello to")    flag.Parse()    fmt.Printf("Hello, %s!\n", *name)

在这段代码中,我们使用了flag包来解析命令行参数。flag.String函数定义了一个字符串类型的参数name,默认值为“World”。flag.Parse函数解析命令行参数,并将结果存储在name变量中, 最后,使用fmt.Printf函数打印出问候语。

E:\go\go-orm-learn\go> go run .\command_line.go -name=xiaomingHello, xiaoming!

给name传入xiaoming,那么就输出Hello, xiaoming!

进阶示例

为了让我们的CLI工具更加强大,我们可以添加更多功能,比如支持多个参数、子命令等。下面是一个稍微复杂一点的例子:

处理多个参数

    name := flag.String("name", "World", "a name to say hello to")    age := flag.Int("age", 0, "age of the person")    flag.Parse()    if *age > 0 {        fmt.Printf("Hello, %s! You are %d years old.\n", *name, *age)    } else {        fmt.Printf("Hello, %s!\n", *name)    }

在这个例子中,我们增加了一个整数类型的参数age,并根据age的值决定输出哪种问候语。


E:\go\go-orm-learn\go> go run .\command_line.go -name=xiaoming -age=18Hello, xiaoming! You are 18 years old.E:\go\go-orm-learn\go>


支持子命令

    helloCmd := flag.NewFlagSet("hello", flag.ExitOnError)    byeCmd := flag.NewFlagSet("bye", flag.ExitOnError)    helloName := helloCmd.String("name", "World", "a name to say hello to")    byeName := byeCmd.String("name", "World", "a name to say goodbye to")    if len(os.Args) < 2 {        fmt.Println("expected 'hello' or 'bye' subcommands")        os.Exit(1)    }    switch os.Args[1] {    case "hello":        helloCmd.Parse(os.Args[2:])        fmt.Printf("Hello, %s!\n", *helloName)    case "bye":        byeCmd.Parse(os.Args[2:])        fmt.Printf("Goodbye, %s!\n", *byeName)    default:        fmt.Println("expected 'hello' or 'bye' subcommands")        os.Exit(1)    }

在这个例子中,我们使用了flag.NewFlagSet函数创建了两个子命令hello和bye,并分别解析它们的参数。根据命令行输入的第一个参数,选择执行相应的子命令

E:\go\go-orm-learn\go> go run .\sub_command.go bye -name=xiaomingGoodbye, xiaoming!E:\go\go-orm-learn\go> go run .\sub_command.go hello -name=xiaomingHello, xiaoming!

Command-Line知识点汇总

功能

示例代码

说明

定义字符串参数

name := flag.String("name", "World", "a name to say hello to")

定义一个字符串类型的参数

定义整数参数

age := flag.Int("age", 0, "age of the person")

定义一个整数类型的参数

解析参数

flag.Parse()

解析命令行参数

创建子命令

helloCmd := flag.NewFlagSet("hello", flag.ExitOnError)

创建一个子命令

解析子命令参数

helloCmd.Parse(os.Args[2:])

解析子命令的参数

获取命令行参数

os.Args

获取命令行参数的切片

处理多个子命令

switch os.Args[1] { case "hello": helloCmd.Parse(os.Args[2:]) }

根据第一个参数选择子命令

打印输出

fmt.Printf("Hello, %s!\n", *name)

打印输出结果

实战案例

让我们来看一个实际的案例,假设我们要开发一个简单的任务管理CLI工具,它可以添加任务、列出任务和删除任务。

定义数据结构

type Task struct {	ID   int    `json:"id"`	Name string `json:"name"`}var tasks []Taskfunc loadTasks() {	file, err := os.ReadFile("tasks.json")	if err != nil {		return	}	json.Unmarshal(file, &tasks)}func saveTasks() {	file, _ := json.MarshalIndent(tasks, "", " ")	os.WriteFile("tasks.json", file, 0644)}

主程序

func main() {	addCmd := flag.NewFlagSet("add", flag.ExitOnError)	listCmd := flag.NewFlagSet("list", flag.ExitOnError)	deleteCmd := flag.NewFlagSet("delete", flag.ExitOnError)	addName := addCmd.String("name", "", "Name of the task to add")	deleteID := deleteCmd.Int("id", -1, "ID of the task to delete")	if len(os.Args) < 2 {		fmt.Println("expected 'add', 'list' or 'delete' subcommands")		os.Exit(1)	}	loadTasks()	switch os.Args[1] {	case "add":		addCmd.Parse(os.Args[2:])		if *addName != "" {			task := Task{ID: len(tasks) + 1, Name: *addName}			tasks = append(tasks, task)			saveTasks()			fmt.Printf("Added task: %v\n", task)		}	case "list":		listCmd.Parse(os.Args[2:])		for _, task := range tasks {			fmt.Printf("%d: %s\n", task.ID, task.Name)		}	case "delete":		deleteCmd.Parse(os.Args[2:])		if *deleteID > 0 {			for i, task := range tasks {				if task.ID == *deleteID {					tasks = append(tasks[:i], tasks[i+1:]...)					saveTasks()					fmt.Printf("Deleted task with ID: %d\n", *deleteID)					break				}			}		}	default:		fmt.Println("expected 'add', 'list' or 'delete' subcommands")		os.Exit(1)	}}

在这个案例中,我们实现了一个简单的任务管理CLI工具,可以通过命令行添加、列出和删除任务。任务数据存储在一个JSON文件中,通过解析命令行参数实现不同的功能。

测试命令行工具

// 测试新增任务E:\go\go-orm-learn\go> go run .\command_action.go add -name="7:30 起床"Added task: {1 7:30 起床}E:\go\go-orm-learn\go> go run .\command_action.go add -name="7:45 吃早餐"Added task: {2 7:45 吃早餐}E:\go\go-orm-learn\go> go run .\command_action.go add -name="8:00 去上学"Added task: {3 8:00 去上学}// 测试列出列表任务E:\go\go-orm-learn\go> go run .\command_action.go list1: 7:30 起床2: 7:45 吃早餐3: 8:00 去上学// 测试删除任务E:\go\go-orm-learn\go> go run .\command_action.go delete -id=1 Deleted task with ID: 1E:\go\go-orm-learn\go> go run .\command_action.go list        2: 7:45 吃早餐3: 8:00 去上学


希望大家通过这篇文章对Golang的Command-Line工具开发有一个全面的了解。在实际开发中,CLI工具可以大大提升我们的工作效率。欢迎大家在评论区分享你们的CLI工具开发经验和遇到的问题,如果你喜欢这篇文章,请点赞、关注和分享给更多的朋友。我们下次再见,Happy Coding!