(二)命令行选项

本文介绍了如何在现有的命令行程序中添加新的选项'-l',以便按行显示文件名,扩展了程序的功能,使得用户可以根据需求定制输出格式。

(二)命令行选项

前言

在第一部分,我们实现了一个“简单的命令行程序”-list,用于显示当前目录下的所有文件,文件名之间使用空格分隔。

今天我们一起来增强下 “list” 命令行,给它传递选项。

传递选项的目的

传递选项是为了改变命令行程序的行为。我们之前实现的 list 命令行程序的默认行为是:显示当前目录下的所有文件,文件名称之间使用空格分隔。

现在我们希望通过传递 -l 选项告诉 list 命令行在显示文件名称的时候,每一行只显示一个文件名(即使用换行符分隔)而不是使用空格分隔。

因此我们的目标是:当我们在终端输入以下命令:

list -l

输出当前目录下所有文件的名称,且每行只显示一个文件名。

命令行选项说明

严格来说,命令行选项是键值对,看个例子:

nginx -s reload

我们给 nginx 命令传递了一个选项 ‘-s’,选项的值为 reload。再看一个例子:

ls -l

这里我们给 ls 命令传递一个选项 ‘-l’,但是你会发现这里只有选项,却没有选项的值。一般我们称这种没有值的选项为”开关选项“。可以认为选项的值是 true。当省略选项本身的时候,则相当于:

ls -l false
# 但是我们一般不会这样写,而是直接省略选项
ls

实现方法

回到我们今天的目标本身,实现list -l

这里有两个关键问题:

  • 如何定义选项
  • 如何获取选项的值

在上一篇中,我们实现了列出当前文件夹下的文件名称,并使用空格分隔文件名,主要代码如下:

var rootCmd = &cobra.Command{
	Use:   "list",
	Short: "列出当前文件下的内容",
	Long: `列出当前文件下所有的文件名称,包括文件名和目录名。`,
	Run: func(cmd *cobra.Command, args []string) {
		// 这里写命令行逻辑
		listDirContent()
	},
}

func listDirContent() {
    // 获取当前工作目录
    wd, _ := os.Getwd()
    // 读取目录下的文件
    files, _ := ioutil.ReadDir(wd)
    fileNames := make([]string, 0, len(files))
    for _, file := range files {
        fileNames = append(fileNames, file.Name())
    }
    fmt.Println(strings.Join(fileNames, " "))
}

如果传递了 “-l” 选项,则使用换行符分隔文件名。使用换行符分隔文件名很简单,我们只需要修改下 listDirContent 方法,给他添加一个参数:分隔符。

func listDirContent(sep string) {
    // ... 内容和上面的相同,这里省略。
    fmt.Println(strings.Join(fileNames, sep))
}

让我们回到 root.go 中看看 init 方法

func init() {
	cobra.OnInitialize(initConfig)
	
	// 定义了config选项
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.xtools-guide.yaml)")
	// 定义了toggle选项
	rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

cobra-init 生成的命令,已经包含了两个选项:一个是 config,一个是 toggle。我们再定义一个 “-l” 选项。

rootCmd.Flags().BoolP("lst", "l", false, "列出文件名,并使用换行符分隔")

可以看到,选项的定义是通过 Flags() 下的各种变体方法完成的。上面的 BoolP 就是用来定义开关型选项的方法。第一个参数是选项的“长名称”,即 lst;第二个参数是选项的“短名称”,即 l;第三个参数是选项的默认值,最后一个参数是选项的帮助信息。

在执行命令的时候,我们可以使用选项“长名称”,也可以使用“短名称”,就拿上面的例子来说,下面两种运行方式是等价的:

list --lst
list -l

注意:长名称前有两个横线,短名称只需要一个横线。长名称更便于理解选项的含义,但是短名称书写更简洁。

一行代码我们就完成了选项的定义,接下来我们要获取选项的值。并根据选项的值决定使用换行还是空格分隔文件名。获取选项的值也很简单:

var rootCmd = &cobra.Command{
	Use:   "list",
	Short: "列出当前文件下的内容",
	Long: `列出当前文件下所有的文件名称,包括文件名和目录名。`,
	Run: func(cmd *cobra.Command, args []string) {
		// 注意:需要通过长名称获取选项的值
		value, _ := cmd.Flags().GetBool("lst")
		sep := " "
		if value {
			sep = "\n"
		}
		listDirContent(sep)
	},
}

func listDirContent(sep) {
	// ...
}

可以看到获取选项的值是通过 Flags().GetXX()方法获取,由于我们定义的选项是开关类型,所有通过 GetBool 获取。如果选项是其它类型,还有 GetString、GetInt 等获取选项值的方法。

完整代码放在 github 上,戳这里查看。或者 clone 整个 list 项目,切换到 easy-command-part2 分支查看。

牛刀小试

go run main.go -l
# 或者
go build
./list -l

如果没有意外,应该能看到命令行输入了当前目录下的所有文件名,且每行一个文件名。

LLM驱动的 A/H/美股智能分析器,多数据源行情 + 实时新闻 + Gemini 决策仪表盘 + 多渠道推送,零成本,纯白嫖,定时运行。基于大模型驱动,支持 A/H/美股多市场全覆盖,自动分析自选股,生成精确买卖点和多维度深度报告。它集成了实时行情、多渠道推送、智能决策仪表盘,内嵌市场策略和AI复盘,甚至能通过图片识别快速添加自选股,零成本、开源,定时自动运行,极适合个人投资者和量化爱好者。主要功能:- 一句话核心结论+买卖点+操作清单,助力精准决策- 技术面、筹码、舆情、新闻多维度综合分析- A股/港股/美股及主流指数实时行情支持- 策略引擎支持多种市场策略与复盘分析- AI智能问股Bot,多策略多轮问答,解读技术细节- 多平台推送:企业微信、飞书、Telegram、邮件等适合想用AI提升选股效率,降低盯盘压力的人。功能特性模块功能说明AI决策仪表盘一句话核心结论 + 精确买卖点位 + 操作检查清单分析多维度分析技术面(盘中实时 MA/多头排列)+ 筹码分布 + 舆情情报 + 实时行情市场全球市场支持 A股、港股、美股及美股指数(SPX、DJI、IXIC 等)策略市场策略系统内置 A股「三段式复盘策略」与美股「Regime Strategy」,输出进攻/均衡/防守或 risk-on/neutral/risk-off 计划,并附“仅供参考,不构成投资建议”提示复盘大盘复盘每日市场概览、板块涨跌;支持 cn(A股)/us(美股)/both(两者) 切换图片识别从图片添加上传自选股截图,Vision LLM 自动提取股票代码,一键加入监控回测AI 回测验证自动评估历史分析准确率,方向胜率、止盈止损命中率Agent 问股策略对话多轮策略问答,支持均线金叉/缠论/波浪等 11 种内置策略
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值