制作一款CLI工具是件有成就感的事!
如何快速制作一款CLI工具,就是命令行工具,比如echo这种。
票圈大神们贡献了一大波方法,我先进行一波总结。
比如Java语言的SpringShell,可以和SpringBoot一起制作一款命令行工具,比如以下写法。
ShellComponent
publicclassSSHCommand{
ShellMethod(valueconnecttoremoteserver)
publicvoidssh(ShellOption(values)Stringhost){
System。out。println(host);
}
}
即可支持一条ssh命令,并附带s参数。
shell:sshs192。168。0。3
192。168。0。3
用java给自己做一款这样的小工具集,还是非常方便的。当然如果你不想使用Spring,也有JCommander这样的工具,不依赖Spring套件,只不过写法就会比较丑陋。
除了java语言,大家推荐最多的还是Go语言的Cobra库,官网cobra。dev非常简洁。
具体大家去官网看吧,都是非常直观明了的demo,非常舒服。其他的我还没有详细调研过,这里把票圈反馈都说下:
dpdk
python的click
C的boost
rustclap
nodejs
javacommoncli包
urfavecli
xterm。js
cpp的boost
不过没有提到C语言的,倒是有位读者提到了getopt系列函数,这个是什么呢?
先不说这个函数是什么,你知道你常用的那些命令,像echo,cp,mv这些,都是由谁提供的么?
这些都属于coreutils工具类,比如cpversion就可以看到具体的版本信息。
既然这些CLI工具类都是coreutils里的代码,那我们看看这里的实现方式,一定是比较优雅的。
打开coreutils的源码,随便找个命令,比如basename。c找到它的main方法,可以看到就是使用了getoptlong来解析的命令行参数。
那要说实现的优雅度,我们和coreutils里的实现方式一样,总归是没有错的。
不过getoptlong具体怎么使用呢?我们man一下它,就可以看到非常详细的介绍,下面还有特别简单的demo,可以直接编译运行的。
对比发现,这demo和coreutils里的用法大体结构是一样的,都是while循环里不断调用getoptlong函数解析或者的参数,然后通过switch判断返回值c的值,来执行不同的操作。
同时,将longoptions也是就参数列表放在一个数组中,使用requiredargument表示需要参数,noargument表示无需参数。
这时我有个想法,如果自己实现一套coreutils,不但能学习到使用C语言制作一款优雅的CLI工具的方法,还能对常用shell命令有一个深入源码式的了解,同时我们也可以改造这些命令使其具有我们自己的特性,还可以为今后增加自己的新命令打下基础。
同时,coreutils里很多命令的底层,也是需要调用Linux系统库的,我们也可以对一些系统库函数有更多的了解。
一举好多的呀!开干!
coreutils中有个特别有趣且简单的命令,yes,你在Linux命令行里输入yes按下回车,会发现它持续不断输出y在命令行中,非常快,就是这效果。
我是不是可以自己实现一套,并对其进行改造,让它可以输出行号,并且控制输出的时间间隔,别那么快。
说干就干,一款dbfyes工具就做出来了。
它可以支持用n参数表示输出行号,用s参数表示时间间隔秒数,最后跟一个参数hehe表示要输出的字符是什么。
感觉这个学习方式还是非常不错的,涉及到的知识点不少,而且又非常有成就感,像闯关一样把coreutils里面的全部工具都实现一遍,增加自己的特性。
后续可能考虑出一个这样的系列,通过实现一套coreutils,讲述一大堆底层的原理和使用方式,我个人觉得这方法真心不错。
关于dbfyes的源码可以在GitHub上找到,点击下方阅读原文就可以跳转,后续该项目会持续迭代。