之前在朋友圈求助过|制作一款cli工具是件有成就感的事

之前在朋友圈求助过 , 如何快速制作一款CLI工具 , 就是命令行工具 , 比如echo这种 。
票圈大神们贡献了一大波方法 , 我先进行一波总结 。
比如Java语言的SpringShell , 可以和SpringBoot一起制作一款命令行工具 , 比如以下写法 。 @ShellComponentpublicclassSSHCommand{@ShellMethod(value="https://pcff.toutiao.jxnews.com.cn/p/20230109/connecttoremoteserver")publicvoidssh(@ShellOption(value="https://pcff.toutiao.jxnews.com.cn/p/20230109/-s")Stringhost){System.out.println(host);}}
即可支持一条ssh命令 , 并附带-s参数 。 shell:ssh-s192.168.0.3192.168.0.3
用java给自己做一款这样的小工具集 , 还是非常方便的 。 当然如果你不想使用Spring , 也有JCommander这样的工具 , 不依赖Spring套件 , 只不过写法就会比较丑陋 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事
文章图片
除了java语言 , 大家推荐最多的还是Go语言的Cobra库 , 官网cobra.dev非常简洁 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事
文章图片
具体大家去官网看吧 , 都是非常直观明了的demo , 非常舒服 。 其他的我还没有详细调研过 , 这里把票圈反馈都说下:
dpdk
python的click
C++的boost
之前在朋友圈求助过|制作一款cli工具是件有成就感的事】rustclap
nodejs
javacommon-cli包
urfave/cli
xterm.js
cpp的boost
不过没有提到C语言的 , 倒是有位读者提到了getopt系列函数 , 这个是什么呢?
先不说这个函数是什么 , 你知道你常用的那些命令 , 像echo , cp , mv这些 , 都是由谁提供的么?
这些都属于coreutils工具类 , 比如cp--version就可以看到具体的版本信息 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事
文章图片
既然这些CLI工具类都是coreutils里的代码 , 那我们看看这里的实现方式 , 一定是比较优雅的 。
打开coreutils的源码 , 随便找个命令 , 比如basename.c找到它的main方法 , 可以看到就是使用了getopt_long来解析的命令行参数 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事
文章图片
那要说实现的优雅度 , 我们和coreutils里的实现方式一样 , 总归是没有错的 。
不过getopt_long具体怎么使用呢?我们man一下它 , 就可以看到非常详细的介绍 , 下面还有特别简单的demo , 可以直接编译运行的 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事
文章图片
对比发现 , 这demo和coreutils里的用法大体结构是一样的 , 都是while循环里不断调用getopt_long函数解析-或者--的参数 , 然后通过switch判断返回值c的值 , 来执行不同的操作 。
同时 , 将long_options也是就--参数列表放在一个数组中 , 使用required_argument表示需要参数 , no_argument表示无需参数 。
这时我有个想法 , 如果自己实现一套coreutils , 不但能学习到使用C语言制作一款优雅的CLI工具的方法 , 还能对常用shell命令有一个深入源码式的了解 , 同时我们也可以改造这些命令使其具有我们自己的特性 , 还可以为今后增加自己的新命令打下基础 。
同时 , coreutils里很多命令的底层 , 也是需要调用Linux系统库的 , 我们也可以对一些系统库函数有更多的了解 。
一举好多的呀!开干!
coreutils中有个特别有趣且简单的命令 , yes , 你在Linux命令行里输入yes按下回车 , 会发现它持续不断输出y在命令行中 , 非常快 , 就是这效果 。
之前在朋友圈求助过|制作一款cli工具是件有成就感的事