前言

针对golang这门高级语言,主要想了解它的语言特性还有服务器建站还有微服务搭建方面的用途,以下都可以算是使用记录。

一、命令行应用的标准库实现

很多语言都有针对命令行参数的功能包,比如python的argparse和golang的flag两个标准库,对于不少c/cpp程序员来说,最直显的就是main函数的argc和argv两个运行参数了,使用效果就是平时输入命令的各种参数:

# 删库跑路专用
rm -rf /*

如上面的rm命令,rf就是它的执行参数,负责告知rm,把根目录下所有文件、文件夹和子文件夹都给我干掉的意思并且是强行删除不问询。高级语言针对针对命令行参数已经封装好只需要调用函数传入参数即可,不像c/cpp还需要针对输入参数来写逻辑处理,同样的场景有不同的使用,相对而言高级语言拿来就用不用造轮子是为了方便实现,c/cpp很多都是自定义的造轮子所以更像原有功能不满意所以自己造一个来用,算是有深入了解的高手的语言吧。

1.1 实现一个简单带命令参数的应用

golang标准库flag的使用比较简单,如下:

func main(){
var name string
flag.StringVar(&name, "name", "作者", "帮助信息")
flag.StringVar(&name, "n", "author", "帮助信息") var age int
flag.IntVar(&age, "age", 18, "年龄")
flag.IntVar(&age, "a", 80, "年龄")
flag.Parse() fmt.Printf("author: %s, age: %d\n", name, age)
}

输出如下:

# golang可以直接run也可以进行编译再运行,这里编译了可执行文件再执行
jam:~$ go build .
jam:~$ ./gotour -h
Usage of ./gotour:
-a int
age (default 80)
-age int
年龄 (default 18)
-n string
帮助信息 (default "aaa")
-name string
帮助信息 (default "bbb")
jam:~$ ./gotour
author: bbb, age: 80
jam:~$ ./gotour -n jack
author: jack, age: 80
jam:~$ ./gotour --name=jam
author: jam, age: 80
jam:~$ ./gotour -age 29
author: bbb, age: 29
jam:~$

简单的应用就是使用flag的StringVar或者IntVar或BoolVal等api来设置具体类型的参数,都是四个参数,第一个是存储信息的变量,第二个是参数名比如上面的rf,第三个则是这个参数的默认值,如果没有输入该参数,变量就存储默认值,最后一个参数则是提示之类的信息,比如很多linux命令都有help参数,这个就是默认help参数的针对对应参数的解释提示。在上面特定参数设置好以后,进行Parse()调用,就算整体设置完毕。

另一种实现

除了上面四参数的各种Var库函数,还有下面这种:

func main() {
flag.Parse()
name := flag.String("name", "jam", "作者")
age := flag.Int("a", 18, "作者年龄") fmt.Printf("the author: %s, age: %d\n", *name, *age)
}

输出如下:

jam:$ go build .
jam:$ ./gotour
the author: jam, age: 18
jam:$ ./gotour -h
Usage of ./gotour:
-a int
作者年龄 (default 18)
-name string
作者 (default "jam")
jam:$ ./gotour --name Peter
the author: Peter, age: 18
jam:$ ./gotour -a 88
the author: jam, age: 88

要注意的是,针对同一个命令比如上面注明作者这个命令,是哪个调用在前,就使用哪个默认值,另外就是Parse的调用可以在参数设置完以后也可以一开始就调用。还有就是注意别设置重复的命令参数,冲突起来大概就只能谁先谁后了。

1.2 实现有子命令的应用

当一个命令应用具备越来越多的功能时,就会变得臃肿,需要几个主命令参数,其下子命令负责更细致的划分,比如用的较多的linux安装命令:

# centos
yum list installed # ubuntu
apt list --installed

上面两个命令的执行可以得到各自系统的对应已安装包列表(不过安装方式要对应yum或者apt就是了),上面list参数就是列出列表的意思,后面installed参数则是指明列表内容,它就是对应list的命令集下的子命令了。使用flag标准库实现一下:

func main() {
flag.Parse()
args := flag.Args() if len(args) <= 0 {
return
} switch args[0] {
case "cat":
showCmd := flag.NewFlagSet("cat", flag.ExitOnError)
showCmd.StringVar(&something, "s", "abaaba", "简单输出")
showCmd.StringVar(&something, "sentence", "小aba", "输出")
_ = showCmd.Parse(args[1:])
case "want":
wantCmd := flag.NewFlagSet("want", flag.ExitOnError)
wantCmd.StringVar(&something, "book", "计算机科学", "书名")
wantCmd.StringVar(&something, "b", "计算机网络", "书名")
_ = wantCmd.Parse(args[1:])
} fmt.Printf("the something:%s\n", something)
}

输出如下:

jam:~$ ./gotour
jam:~$ ./gotour -h
Usage of ./gotour:
jam:~$ ./gotour cat
the something:小aba
jam:~$ ./gotour want -b 火影忍者
the something:火影忍者
jam:~$

二、命令行应用的cobra库实现

因为要用到外部库cobra, 所以先安装一下吧,我这里的IDE是goland和配置好了的vscode环境,但都需要在对应位置输入下面命令:

go get -u github.com/spf13/cobra

关于库的使用,都是了解个用法,重要还是例子:

var versionCmd = &cobra.Command{
Use: "version",
Short: "版本号",
Long: "输出版本号",
Run: func(cmd *cobra.Command, args []string) {
version := "1.0.0"
if len(args) > 1 {
version = args[1]
}
fmt.Println("gocmd version :", version)
},
} func main() {
err := versionCmd.Execute()
if err != nil {
log.Fatal("命令执行失败:%v", err)
}
}

输出如下:

jam:~$  go build
jam:~$ ./cmdpra -h
输出版本号 Usage:
version [flags] Flags:
-h, --help help for version
jam:~$ ./cmdpra version 2.0.0
gocmd version : 2.0.0

对照flag标准库,cobra的使用也需要四部分信息:命令参数, 短描述, 长描述和命令处理(和flag稍微有点不同), cobra内置了Command数据结构来存储对应信息,命令的调用也就是一个Command对象调用Execute即可,如上是单个命令的实现,

要实现多个命令统一子命令就需要使用cobra的AddCommand接口了:

var catCmd = &cobra.Command{
Use: "cat",
Short: "something",
Run: func(cmd *cobra.Command, args []string) {
s := "nothing"
if len(args) > 1 {
s = args[1]
}
fmt.Println("cat ", s)
},
} var versionCmd = &cobra.Command{
Use: "version",
Short: "版本号",
Long: "输出版本号",
Run: func(cmd *cobra.Command, args []string) {
version := "1.0.0"
if len(args) > 1 {
version = args[1]
}
fmt.Println("gocmd version :", version)
},
} func main() {
rootCmd := &cobra.Command{}
rootCmd.AddCommand(catCmd)
rootCmd.AddCommand(versionCmd)
err := rootCmd.Execute()
if err != nil {
log.Fatal("命令执行失败:%v", err)
}
}

不过一般来说,项目会根据情况进行解偶,所以这些个子命令的设置一般会设定在cmd包里,再来内部调用,到时候main包就只需要进行一个Execute即可,上面输出如下:

jam:~$ ./cmdpra
Usage:
[command] Available Commands:
cat something
help Help about any command
version 版本号 Flags:
-h, --help help for this command Use " [command] --help" for more information about a command.
jam:~$ ./cmdpra cat abaaba
cat nothing

除此以外,添加子命令的方式也可以类似标准库的StringVar,如下:

var str string

var catCmd = &cobra.Command{
Use: "cat",
Short: "something",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("gocmd version: %s\n", str)
},
} func main() {
rootCmd := &cobra.Command{}
rootCmd.AddCommand(catCmd)
catCmd.Flags().StringVarP(&str, "version", "v", "v1.0.0", "版本号")
err := rootCmd.Execute()
if err != nil {
log.Fatal("命令执行失败:%v", err)
}
}

flag标准库的StringVar需要四个参数,两次调用就可以有v和version两个子命令参数的实现,cobra.StringVarP一个接口五个参数就实现,算是可以打字少一点。对应输出就是下面了:

jam:~$ ./cmdpra cat --version=v2.0.0
gocmd version: v2.0.0
jam:~$ ./cmdpra cat
gocmd version: v1.0.0
jam:~$ ./cmdpra
Usage:
[command] Available Commands:
cat something
help Help about any command Flags:
-h, --help help for this command Use " [command] --help" for more information about a command.
jam:~$

CLI命令行应用的更多相关文章

  1. ThinkPHP3.1.2 使用cli命令行模式运行

    ThinkPHP3.1.2 使用cli命令行模式运行 标签(空格分隔): php 前言 thinkphp3.1.2 需要使用cli方法运行脚本 折腾了一天才搞定 3.1.2的版本真的很古老 解决 增加 ...

  2. PHP的CLI命令行运行模式浅析

    在做开发的时候,我们不仅仅只是做各种网站或者接口,也经常需要写一些命令行脚本用来处理一些后端的事务.比如对数据进行处理统计等.当然也是为了效率着想,当一个事务有可能会有较长的耗时时,往往会交由服务器的 ...

  3. golang常用库:cli命令行/应用程序生成工具-cobra使用

    golang常用库:cli命令行/应用程序生成工具-cobra使用 一.Cobra 介绍 我前面有一篇文章介绍了配置文件解析库 Viper 的使用,这篇介绍 Cobra 的使用,你猜的没错,这 2 个 ...

  4. Jenkins CLI命令行

    Jenkins CLI命令行 jenkins不光可以UI操作还提供了命令行接口 位置 首页->系统管理->工具和动作->Jenkins 命令行接口 在这个界面下载一个jenkins- ...

  5. Apache Commons CLI命令行启动

    今天又看了下Hangout的源码,一般来说一个开源项目有好几种启动方式--比如可以从命令行启动,也可以从web端启动.今天就看看如何设计命令行启动... Apache Commons CLI Apac ...

  6. GO语言之urfave/cli命令行解析

    练习URL: https://blog.csdn.net/sd653159/article/details/83381786 相信只要部署过线上服务,都知道启动参数一定是必不可少的,当你在不同的网络. ...

  7. Angular CLI 命令行工具

    工欲善其事必先利其器.好的工具让开发更加简单便捷. 1.全局安装angular cli npm install -g @angular/cli 2.安装完成后就可以使用angular-cli命令行工具 ...

  8. CI 框架下执行CLI(命令行)

    1.可以按照Ci官方文件的指导来进行操作 让我们先创建一个简单的控制器,打开你的文本编辑器,新建一个文件并命名为 Tools.php,然后输入如下的代码: <?php class Tools e ...

  9. Go语言中的IO操作、Flag包以及urfave/cli命令行框架

    一.格式化输入和输出 1.从终端获取用户的输入 fmt.Scanf  空格作为分隔符,占位符和格式化输出的一致 fmt.Scan  从终端获取用户的输入,存储在Scanln中的参数里,空格和换行符作为 ...

  10. 开发CLI命令行

    命令行工具:CLI 是在命令行终端使用的工具,如git, npm, vim 都是CLI工具.比如我们可以通过 git clone 等命令简单把远程代码复制到本地 和 cli 相对的是图形用户界面(gu ...

随机推荐

  1. biancheng-Spring MVC-HandlerMapping

    一.HandlerMapping 作用是根据当前请求的找到对应的 Handler,并将 Handler(执行程序)与一堆 HandlerInterceptor(拦截器)封装到 HandlerExecu ...

  2. springBoot(1)--初步理解

    在没有用SpringBoot之前,我们用spring和springMVC框架,但是你要做很多比如: (1)配置web.xml,加载spring和spring mvc 2)配置数据库连接.配置sprin ...

  3. YUV 格式

    1. YUV比例 分三种:YUV44,YUV422,YUV420 2. YUV排布 分三种:YUV planar,YUV Semi-Plannar,YUV packed 以YUV422 8*4 为例 ...

  4. [rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(04):实现窗口主题(颜色)变换(暨menu菜单的使用)

    前言 本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发. iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动. 本合集是基于新版本的关于分 ...

  5. java中的HashSet

    什么是HashSet 在 Java 中,HashSet 是一个基于哈希表实现的集合类,它实现了 Set 接口 HashSet 的主要特点是:1,2 HashSet 的主要特点是 1,集合中的数据不能够 ...

  6. Kubernetes 轻松管理资源

    资源管理介绍 在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes. kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务,所谓的部署 ...

  7. Asp.Net Core3.0 微信小程序统一下单

    微信统一下单开发文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1 微信支付小程序支付文档:https://pay.wei ...

  8. IPTools for .NET:快速查询全球IP信息

    IPTools 是一个用于快速查询全球 IP 地址信息的库,支持国内和国际 IP 查询,提供详细的地理位置信息(如国家.省份.城市)以及经纬度等数据. 1. IPTools.China IPTools ...

  9. 从龟速乘到 $Miller-Rabin$ 算法(数论算法总结)

    发现自己竟然菜到不太会龟速乘,所以把 \(Miller-Rabin\) 算法所需要用到的算法全学了一遍-- 龟速乘 龟速乘是一种 \(O(\log n)\) 的乘法计算方法. 考虑有时普通乘法取模会爆 ...

  10. QT5笔记:5. QtCreator 的快捷键

    常用的快捷键: F4 同名头文件和源文件之间切换 F2 声明和定义切换 Ctrl + / 注释 F10\F11 单步调试