服务计算3 开发 Linux 命令行实用程序

概述

本次作业参考潘老师的博客
https://pmlpml.github.io/ServiceComputingOnCloud/ex-cli-basic

github传送门
https://github.com/ddghost/Sevice-Computing/tree/CLI-命令行实用程序开发基础

本次作业主要是编写一个命令行程序,处理标准输入或者文本文件。程序的要求主要参考、https://www.ibm.com/developerworks/cn/linux/shell/clutil/index.html

1.解析参数

对于命令行程序,首先要做的就是解析命令行传入的参数,例如执行程序

./selpag -s 1 -e 1 input.txt

对于这个命令,我们这个程序应该要至少有三个变量,一个记录-s后的1,一个记录-e后的1,一个记录input.txt。
传入的参数是命令行程序最重要的东西。解析可以使用os库里的os.Args,但是这很麻烦。
所幸已经有前人帮我们完成解析参数的工作,那就是使用flag或者pflag库。这两个库的使用可以参考
https://o-my-chenjian.com/2017/09/20/Using-Flag-And-Pflag-With-Golang/

在命令行输入以下代码获得pflag包,而flag包不用获取

go get github.com/spf13/pflag

由于老师要求使用pflag,这里给出pflag简单的代码使用,例如对于IntVarP,五个参数分别是,变量的地址,长名,短名,默认值,帮助时的语句。

	flag.IntVarP(&page_len , "l", "l" , 72, "page length")
	flag.BoolVarP(&help , "h", "h", false, "show help")
	flag.StringVarP(&print_dest , "d", "d" , "", "print detination")

对于传入的参数,以下两种情况是等价的,它们都会把page_len赋值为11。

./selpage -l 11
./selpage -l=11
./selpage --l 11
./selpage --l=11

将变量名和传入的参数绑定后,使用parse就可以解析了,注意不要忘了,否则忘了解析各变量的值都是默认的。

flag.parse()

对于传入的前面是‘-’的参数,可以用pflag提前绑定好变量,但是这次传入的文件名参数,前面是没有‘-’的,这里只要注意 pflag 会把不能解析的参数都放在Args()数组里面,因此调用flag.Args()[0]就可以获得第一个没被解析成flag的参数,也就是文件名。

2.命令行的’<’,’>’,’|'符号

在实现要求中,展示了程序在命令行中搭配’<’ , ‘>’ , ‘|’ 符号的操作,我对命令行的操作并不是太熟悉,开始还很奇怪为什么输入之后用pflag解析不了。
后来发现这些符号的效果并不需要我们实现,它们是linux命令行自带的效果,和‘&’符号一样。

3.执行命令行的命令

本部分参考
https://godoc.org/os/exec#example-Command

在本次作业中,需要在程序里执行一个命令行的命令lp,因此要用到os/exec包,简要的代码如下。
exec.Command后面的传入的参数就是命令行要执行的命令还有参数,例如想执行“cat tmp.txt“,就应该传入"cat"和 “tmp.txt”,简单来说就是将空格分开的部分分别写进去。
然后cmd.StdinPipe()就是lp命令的输入管道,lp的输入接受本程序的输出。
然后后面cmd.Start执行命令行程序。
如果3秒后还没执行完,进行终止。

			cmd = exec.Command("lp" , "-d" , print_dest)
			fout, err = cmd.StdinPipe()
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1) 
			}
			outputFile(inputFile , fout)
			fout.Close()
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			err = cmd.Start()
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1) 
			}
			timer := time.AfterFunc(3*time.Second, func() {
				cmd.Process.Kill()
			})
			err = cmd.Wait()
			timer.Stop()

4.总结

还记得老师布置作业的时候说这次作业很简单,很快就能写完,但是在国庆的时候我花了好几天才写完,光是文档都看了好久。最主要的问题还是对linux命令行很多东西都不是太熟悉,还有第一次写go程序也不太熟练的缘故。

猜你喜欢

转载自blog.csdn.net/DDghsot/article/details/83002174