编写 golang 命令行小工具

该文章展示了如何用Go语言编写一个命令行小工具,通过路由匹配的方式来处理不同的命令选项。代码示例中,创建了一个路由映射,键为选项,值为包含描述和处理函数的结构体。当程序启动时,根据传入的命令参数执行相应的动作。如果未找到匹配的选项,则打印帮助信息。
摘要由CSDN通过智能技术生成

1. 前言

把想了很久的命令行小工具写了个demo。前几天看了 7 天仿 gin 项目,于是今天借鉴了其路由匹配方式,写出了这个demo。
思路是:创建一个类似路由的map,key值为选项,value为选项信息的结构体,结构体中保存有选项的动作函数。程序启动时实例化一个路由map并初始化,然后进行选项匹配,如果map中有这个选项的key,就执行对应的动作。思路很简单。
以下是代码,注释都有。为了管理方便我把源码拆分成了三份:main文件main.go,route相关定义的文件route.go,动作函数文件optionFunc.go

2. 代码部分

main.go

package main

import (
	"fmt"
	"os"
)

func main() {
	//route参数信息,只有选项没有参数的可以不写参数,参数动作函数集中到了optionFunc.go文件中
	//新的选项直接写在下面,动作函数handle也要写在optionFunc.go文件中
	var router = route{
		"-v": commandInfo{
			desc:   "Show version",
			handle: version,
		},
		"-cdb": commandInfo{
			desc:   "批量创建文件夹,参数后写 '路径' '文件夹前缀' '创建数目'",
			params: params{"路径", "文件夹前缀", "创建数目"},
			handle: branchCreateDir,
		},
	}

	//没有选项就打印帮助信心
	if len(os.Args) == 1 {
		printHelp(router)
		return
	}

	// -h 选项打印帮助信息
	//因为涉及到route,所以单独把 -h 摘取出来
	if os.Args[1] == "-h" {
		printHelp(router)
		return
	}

	//匹配到选项就执行选项信息中的动作,不然打印提示
	if commanInfo, ok := router[os.Args[1]]; ok {
		commanInfo.handle(os.Args[1:])

	} else {
		fmt.Printf("unknown flag '%s', please use '-h' to get help info\n", os.Args[1])
	}
}

// 打印帮助信息的函数
func printHelp(router route) {
	fmt.Printf("Usage:\n  %s [OPTIONS]\n\nOptions:\n", os.Args[0])
	for k, v := range router {
		if v.params == nil {
			fmt.Printf("  %s\t%s\n", k, v.desc)
		} else {
			fmt.Printf("  %s [ ", k)
			for _, item := range v.params {
				fmt.Printf("%s ", item)
			}
			fmt.Printf("]\t%s\n", v.desc)
		}

	}
}

route.go

package main

type params []string

// 选项的动作函数
type handFunc func(values params)

// 保存选项的动作、参数说明和选项功能的信息
type commandInfo struct {
	handle handFunc
	desc   string
	params params
}

// 将选项和动作成对存在map里
type route map[string]commandInfo

optionFunc.go

package main

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"strings"
)

func version(params params) {
	fmt.Println("hanta-tools version 0.1.0")
}

func branchCreateDir(params params) {
	//参数个数或者关键参数为空直接提示错误
	if len(params) != 4 || params[1] == "" || params[3] == "" {
		fmt.Printf("  %s ERROR: 请输入正确的参数", os.Args[0])
		return
	}

	//字符串转数字失败提示参数错误
	num, err := strconv.Atoi(params[3])
	if err != nil {
		fmt.Printf("  %s ERROR: 请输入正确的文件数", os.Args[0])
		return
	}
	//剔除路径后的 “\” 和 “/” 符号
	prePath := strings.TrimRight(params[1], "\\")
	prePath = strings.TrimRight(prePath, "/")
	for i := 1; i <= num; i++ {
		var dirPath = ""
		//根据不同系统平台来拼接完整路径
		if runtime.GOOS == "windows" {
			dirPath = fmt.Sprintf("%s\\%s%d", prePath, params[2], i)
		} else {
			dirPath = fmt.Sprintf("%s/%s%d", prePath, params[2], i)
		}
		err := os.Mkdir(dirPath, 0666)
		//将创建失败信息完整打印到控制台
		if err != nil {
			fmt.Printf("  %s ERROR: %s", os.Args[0], err)
			break
		}
	}
}

3. 效果

Windows平台编译后运行效果:
在这里插入图片描述
Centos 7.6编译后运行效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值