CLI命令行应用
前言
针对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命令行应用的更多相关文章
- ThinkPHP3.1.2 使用cli命令行模式运行
ThinkPHP3.1.2 使用cli命令行模式运行 标签(空格分隔): php 前言 thinkphp3.1.2 需要使用cli方法运行脚本 折腾了一天才搞定 3.1.2的版本真的很古老 解决 增加 ...
- PHP的CLI命令行运行模式浅析
在做开发的时候,我们不仅仅只是做各种网站或者接口,也经常需要写一些命令行脚本用来处理一些后端的事务.比如对数据进行处理统计等.当然也是为了效率着想,当一个事务有可能会有较长的耗时时,往往会交由服务器的 ...
- golang常用库:cli命令行/应用程序生成工具-cobra使用
golang常用库:cli命令行/应用程序生成工具-cobra使用 一.Cobra 介绍 我前面有一篇文章介绍了配置文件解析库 Viper 的使用,这篇介绍 Cobra 的使用,你猜的没错,这 2 个 ...
- Jenkins CLI命令行
Jenkins CLI命令行 jenkins不光可以UI操作还提供了命令行接口 位置 首页->系统管理->工具和动作->Jenkins 命令行接口 在这个界面下载一个jenkins- ...
- Apache Commons CLI命令行启动
今天又看了下Hangout的源码,一般来说一个开源项目有好几种启动方式--比如可以从命令行启动,也可以从web端启动.今天就看看如何设计命令行启动... Apache Commons CLI Apac ...
- GO语言之urfave/cli命令行解析
练习URL: https://blog.csdn.net/sd653159/article/details/83381786 相信只要部署过线上服务,都知道启动参数一定是必不可少的,当你在不同的网络. ...
- Angular CLI 命令行工具
工欲善其事必先利其器.好的工具让开发更加简单便捷. 1.全局安装angular cli npm install -g @angular/cli 2.安装完成后就可以使用angular-cli命令行工具 ...
- CI 框架下执行CLI(命令行)
1.可以按照Ci官方文件的指导来进行操作 让我们先创建一个简单的控制器,打开你的文本编辑器,新建一个文件并命名为 Tools.php,然后输入如下的代码: <?php class Tools e ...
- Go语言中的IO操作、Flag包以及urfave/cli命令行框架
一.格式化输入和输出 1.从终端获取用户的输入 fmt.Scanf 空格作为分隔符,占位符和格式化输出的一致 fmt.Scan 从终端获取用户的输入,存储在Scanln中的参数里,空格和换行符作为 ...
- 开发CLI命令行
命令行工具:CLI 是在命令行终端使用的工具,如git, npm, vim 都是CLI工具.比如我们可以通过 git clone 等命令简单把远程代码复制到本地 和 cli 相对的是图形用户界面(gu ...
随机推荐
- Linux 常用脚本命令-lsof、find、rpm、SS、top、vim
1,关机命令 1 shutdown -h now/0 2 halt 3 init 0 4 poweroff 5 举例: 6 shutdown -h 3 ------3分钟后关机(可用shutdown ...
- JAVA调用groovy脚本的方式
一.使用用 Groovy 的 GroovyClassLoader ,它会动态地加载一个脚本并执行它.GroovyClassLoader是一个Groovy定制的类装载器,负责解析加载Java类中用到的G ...
- biancheng-Spring Cloud教程
目录http://c.biancheng.net/springcloud/ 1微服务是什么2Spring Cloud是什么3Spring Cloud Eureka4Spring Cloud Ribbo ...
- Calendar日历类(抽象类)的使用
4. java.util.Calendar( 日历)类 类 Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能. 获取Calendar实例的方法 使用Calendar.get ...
- 让你看懂dart中静态成员和继承
静态属性和静态方法 在dart中,我们可以通过关键字 static来定义静态属性和静态方法. 需要注意的是: 静态方法不能访问非静态属性[结论1] 非静态方法可以访问静态成员[结论2] 我们通过下面的 ...
- 访问控制模型 ABAC 的使用和设计原则
访问控制(AC)的发展历程 访问控制(Access Control, AC)是保护系统资源的重要机制,决定"谁"可以访问"哪些"资源,并能执行"哪些操 ...
- 同事PPT又拿奖了?偷偷用这AI工具,3步做出老板狂赞的年度报告
大家好,我是六哥,今天为大家分享一款PPT辅助神器,年底汇报必备神器!就是Napkin AI ! 这是一款超级酷的工具,它能把你写的文字一秒钟转化为各种炫酷的视觉效果,比如图表.流程图.信息图啥的.如 ...
- Oracle DBA末日or重生?不会APEX=淘汰!
残酷现实:传统DBA正在消失 "只会调优SQL的DBA,正在沦为数据库修理工!" 掌握APEX的DBA,薪资翻3倍,秒变企业核心资产! 一.DBA的死刑通知书 1. 云+AI:直接 ...
- 一个nginx + vue下二级路径版本化方案
PS: 尽量不要做版本化!尽量不要做版本化!尽量不要做版本化! 过程说明: 1.arg_appver表示读取url上appver参数 2.对appver参数做变量映射得到alias_party1_te ...
- manim边学边做--向量相关的场景类
VectorScene是Manim动画库中专门用于向量空间可视化的场景类,继承自基础 Scene 类. 它通过封装一系列向量操作方法,使数学教育.物理模拟等领域的动画制作更加高效. 本文主要介绍Vec ...