服务计算——Golang开发CLI命令行实用程序

使用Golang开发CLI命令行程序selpg

参考网站或博客:
Tomy-Lee的GitHub里面有很厉害的selpg程序,学长好厉害啊,我是照着学长打下来的,还有很多不明白的,百度百度解决了很多,剩下的要起码先把作业交上再说……
CLI:使用Go开发命令行应用 这篇文章中介绍了使用Go语言开发CLI的基本知识。
服务计算——selpg命令行程序这篇学长的博客教我怎么写这个Go程序
Golang flag包使用笔记 这篇文章中我们可以学到开发CLI所必须的flag包的使用方法。
开发 Linux 命令行实用程序 这篇文章中提供了写SELPG程序的思路,并提供了C的源码。
Go语言 - 命令行参数(os.Args,flag包)这篇文章更详细的介绍了os包和flag包。

CLI简述

CLI或者“command line interface”是用户在命令行下交互的程序。由于通过将程序编译到一个静态文件中来减少依赖,因此Go特别适合开发CLI程序。

开发CLI程序

CLI程序一般都需要输入参数,比如selpg需要输入的程序名字、起始页码和终止页码。根据老师所给的参考资料,使用string存参数即可。同时,我们可以使用os.Args来获取运行程序时得到的参数。
从前人的经验,我们知道可以使用结构体来进行操作,把C语言结构体改写成Golang形式。
需要注意的是,导入pflag包需要用import flag "github.com/spf13/pflag"方式导入

var progname string 

type selpg_args struct
{
	start_page int
	end_page int
	in_filename string
	page_len int
	page_type int
	print_dest string
}

之后写第一个函数来配置Pflag

func FlagInit(args *selpgargs) {
	flag.IntVarP(&args.start_page, "startPage", "s", -1, "Start page number")
	flag.IntVar(&args.end_page, "endPage", "e", -1, "End page number")
	flag.IntVar(&args.page_len, "pageLength", "l", 72, "Line numbers for a page")
	flag.StringVar(&args.page_type, "type", "f", "l", "Determine form-feed-delimited")
	flag.StringVar(&args.print_dest, "dest", "d", "", "set printer")
	flag.Usage = func () {
		fmt.Printf("%s is a tool to select pages from your chosen file\n\n", progname)
		fmt.Printf("Usage:\n\n")
		fmt.Printf("\tselpg -s start_page -e end_page [-f (speciy how the page is sperated)| -l lines_per_page_default_72] [-d dest] [filename]\n\n")
		fmt.Printf("If no file specified, %s will read input from stdin, and use control-D to end.\n\n", progname)
	}
	flag.Parse()
}

之后使用os.Args来处理参数。需要注意的是读取的第一个参数(即os.Args[0])应为selpg,因此要从os.Args[1]开始处理。以"-s"的处理为例

	if os.Args[1] != "-s" {
		fmt.Fprintf(os.Stderr, "%s: 1st arg should be -s for start_page\n\n", progname)
		flag.Usage()
		os.Exit(1)
	}

在文件处理环节,有如下需要注意的点:

  1. 使用一个流来读入数据。我看学长用的是io.WriteCloser,这里我们要明白标准库的实现是将功能细分,每个最小粒度的功能定义成一个接口,然后接口可以组成成更多功能的接口。也就是说,io.WriteCloser是将Writer和Closer的功能结合,不禁深深感受到了前人的智慧。
  2. 使用flag.NArg()可以判断non-flag的个数。
  3. exec.Cmd可以获得一个外部的程序,我们用这个和命令行绑定。用cat命令来观看并打印文件,使用exec.Command命令让cmd执行cat。
  4. 注意Command只会对命令进行封装,即告诉系统进行什么操作,因此我们还需要连接到命令执行时的pipe获得相关信息。

我的代码保存在了Gitee:Gitee地址

你可能感兴趣的:(服务计算)