文章目录

  • Golang开发Linux命令行实用程序 - selpg
    • 1. 介绍
    • 2. 设计与实现
      • 2.1 设计思路
      • 2.2 功能模块划分与实现
    • 3. 参考文献

Golang开发Linux命令行实用程序 - selpg

1. 介绍

  • Linux命令行使用程序 - selpg,这个名称代表SELect PaGes。selpg允许用户指定从输入文本抽取的页的范围,这些输入文本可以来自文件或另一个进程。
  • 关于selpg的详细介绍,参照开发Linux命令行实用程序
  • 实现slepg代码
    • 我的 - Golang实现
    • 官方 - C语言实现

2. 设计与实现

2.1 设计思路

  • 理解selpg命令的功能以及处理流程。

  • selpg命令涉及的基本操作

    • 文件的读写
    • 从终端获取输入以及在终端输出

2.2 功能模块划分与实现

  • 构建命令行参数的结构体,由于参数使用的比较多,可以使用一个结构体存储起来,使用起来比较方便

    type selpg_args struct {startPage      intendPage        intinFile         stringpageLen        intpageType       bool // true for -f, false for -lNumberoutDestination string
    }
    
  • 参数解析

    • 使用pflag包对命令行输入参数进行解析
    • 使用 pflag 替代 goflag 以满足 Unix 命令行规范, 参考:Golang之使用Flag和Pflag
    • 获得flag参数后pflag.Parse()函数才能把参数解析出来
    • 使用pflag.Args()来获取未被标记的参数
    // 解析获取参数
    func getArgs(args *selpg_args) {pflag.IntVarP(&(args.startPage), "startPage", "s", -1, "start page")pflag.IntVarP(&(args.endPage), "endPage", "e", -1, "end page")pflag.IntVarP(&(args.pageLen), "pageLen", "l", 72, "the length of page")pflag.BoolVarP(&(args.pageType), "pageType", "f", false, "page type")pflag.StringVarP(&(args.outDestination), "outDestination", "d", "", "print destination")pflag.Parse()other := pflag.Args() // 其余参数if len(other) > 0 {args.inFile = other[0]} else {args.inFile = ""}
    }
    
  • 参数检查

    • 检查输入参数的合法性

      • 是否输入了起始页和结束页
      • 起始页大于1小于结束页以及不能溢出(MaxInt32
      • 结束页大于起始页并且不能溢出(MaxInt32
    • 遇到不合法则输出错误同时结束程序

      // 检查参数合法性
      func checkArgs(args *selpg_args) {if args.startPage == -1 || args.endPage == -1 {os.Stderr.Write([]byte("You shouid input like selpg -sNumber -eNumber ... \n"))os.Exit(0)}if args.startPage < 1 || args.startPage > math.MaxInt32 {os.Stderr.Write([]byte("You should input valid start page\n"))os.Exit(0)}if args.endPage < 1 || args.endPage > math.MaxInt32 || args.endPage < args.startPage {os.Stderr.Write([]byte("You should input valid end page\n"))os.Exit(0)}if (!args.pageType) && (args.pageLen < 1 || args.pageLen > math.MaxInt32) {os.Stderr.Write([]byte("You should input valid page length\n"))os.Exit(0)}
      }
      
  • 执行命令

    • 执行命令部分主要涉及到文件的读取以及写入或者标准输入的获取以及命令行下输出,我们使用到bufio包,至于-dXXX 实现,使用到 os/exec包

    • bufio包介绍与使用

      • bufio包实现了带缓存的 I/O 操作,它封装一个 io.Readerio.Writer 对象,使其具有缓存和一些文本读写功能

        • func NewReaderSize(rd io.Reader, size int) *Reader

          NewReaderSizerd 封装成一个带缓存的 bufio.Reader 对象,缓存大小由 size 指定(如果小于 16 则会被设置为 16)。如果rd的基类型就是有足够缓存的 bufio.Reader 类型,则直接将rd 转换为基类型返回。

        • func NewReaderSize(rd io.Reader, size int) *Reader

          NewReader相当于 NewReaderSize(rd, 4096)

        • func (reader *Reader) ReadBytes(delim byte) (line []byte, err error)

          ReadBytesreader中查找delim并读出 delim 及其之前的所有数据。如果 ReadBytes 在找到 delim 之前遇到错误,则返回遇到错误之前的所有数据,同时返回遇到的错误(通常是 io.EOF)。 只有当 ReadBytes 找不到 delim时,err 才不为 nil

    • os/exec包介绍与使用

      • os/exec包执行外部命令。它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整。

        • func Command(name string, arg ...string) *Cmd

          command返回cmd结构来执行带有相关参数的命令,它仅仅设定cmd结构中的Path和Args参数,如果name参数中不包含路径分隔符,command使用LookPath来解决路径问题,否则的话就直接使用name;Args直接跟在command命令之后,所以在Args中不许要添加命令。我们用该命令创建一个命令对象,参数为子进程路径和子进程参数(可选)

          // 指定运行的程序,实现模拟的打印机
          cmd := exec.Command("./" + args.outDestination)
          
        • func (c *Cmd) StderrPipe() (io.ReadCloser, error)

          StderrPipe返回一个pipe,这个管道连接到command的标准错误,当command命令退出时,Wait将关闭这些pipe

        • func (c *Cmd) StdinPipe() (io.WriteCloser, error)

          StdinPipe返回一个连接到command标准输入的管道pipe。我们可以通过在此处写入传输信息,然后作为子进程的标准输入。

      • 对于-dXXX的实现,创建一个子进程,让其模拟打印机,使用管道将数据传输给子进程,子进程读取管道内传输的信息并且打印出来。

    • 处理流程

      • 判断是否指定输入文件,为空则将标准输入作为输入,否则为文件流

      • 判断是否为-d类型

      • 判断输入类型为-l还是-f,依据要求读取输入,在输出到标准输出

      • 判断起始页数以及结束页数是否满足实际标准

        // 执行命令
        func processInput(args *selpg_args) {// read the filevar reader *bufio.Readerif args.inFile == "" {reader = bufio.NewReader(os.Stdin)} else {fileIn, err := os.Open(args.inFile)defer fileIn.Close()if err != nil {os.Stderr.Write([]byte("Open file error\n"))os.Exit(0)}reader = bufio.NewReader(fileIn)}// output the fileif args.outDestination == "" {// 输出到当前命令行outputCurrent(reader, args)} else {// 输出到目的地outputToDest(reader, args)}
        }
        
        // 输出到当前命令行
        func outputCurrent(reader *bufio.Reader, args *selpg_args);// 输出到指定目的地
        func outputToDest(reader *bufio.Reader, args *selpg_args);
        
    • 具体代码参见Github项目

3. 参考文献

  • PFlag的使用

  • package io

  • Golang之使用Flag和Pflag

  • Golang中os/exec包的用法

  • Golang中bufio包的用法

服务计算 - 3 Golang开发Linux命令行实用程序 - selpg相关推荐

  1. 服务计算作业三——CLI 命令行实用程序开发基础

    服务计算作业三--CLI 命令行实用程序开发基础 18342138 郑卓民 本次作业gitee仓库链接(完整代码) 概述 CLI(Command Line Interface)实用程序是Linux下应 ...

  2. 服务计算 HW3 CLI 命令行实用程序开发基础

    文章目录 一. 概述 二. Golang 的支持 ① 使用 os 包处理参数 ② 使用 flag 包处理参数 三. 开发实践 ① 项目要求 ② 设计说明 1) selpg 定义 2) 代码设计 1. ...

  3. 基于Golang的CLI 命令行程序开发

    基于Golang的CLI 命令行程序开发 [阅读时间:约15分钟] 一. CLI 命令行程序概述 二. 系统环境&项目介绍&开发准备 1.系统环境 2.项目介绍 3.开发准备 三.具体 ...

  4. android上最好的linux终端,如何在带有Termux的Android上使用Linux命令行 | MOS86

    apt install [package name]我们的< APTA入门指南>和< APTA在Ubuntu中安装软件的指南>< APT在Ubuntu中在APT中安装软件 ...

  5. netflix linux_Netflix如何处理故障转移,Anaconda,Linux命令行技巧,Python日期时间库,GDPR,微服务等

    netflix linux 上周,Amjith Ramanujam的页面浏览量超过12,000, 关于Netflix如何在7分钟内完成故障转移的文章是我们失控的热门. 您是否有关于您的组织如何确保最大 ...

  6. 后端开发必知必学的 Linux 命令行大全

    今天跟大家推荐个 Linux 命令行教程:<The Linux Command Line>,中文译名:<Linux 命令行大全>. 该书作者出自自美国一名开发者,兼知名 Lin ...

  7. Linux 命令行的艺术

    Linux 命令行的艺术 前言 基础 日常使用 文件及数据处理 系统调试 单行脚本 冷门但有用 仅限 OS X 系统 仅限 Windows 系统 更多资源 免责声明 熟练使用命令行是一种常常被忽视,或 ...

  8. linux 命令行工具无敌斩

    (feh看图器) 做个摘要哈,文章讲命令行工具的: 截图工具 scrot    查看图片器 feh (要图形界面) 录屏软件若干    文字编辑(又是那俩,你懂得) 数字计算 bc    命令行播放器 ...

  9. Linux命令行技巧

    Linux命令行技巧 命令 描述 • apropos whatis 显示和word相关的命令. 参见线程安全 • man -t man | ps2pdf - > man.pdf 生成一个PDF格 ...

最新文章

  1. hdu 2777(线段树)
  2. 片滚动插件myScroll
  3. 【吾悟】《易经》有感程序人生
  4. SQL与C#结合完整修改 删除信息
  5. c语言2L,求助,R8C 2L 如何在C语言定位常数数组到绝对地址
  6. Oracle10gR5GridControl InstallOnLinux
  7. 独家 | 林元庆告别百度
  8. 不需要的系统垃圾把它杀掉!
  9. linux下python安装包_Linux服务器中安装python包管理工具pip
  10. latex \textsuperscript{\dagger} 报错
  11. 解读住房公积金提取买房、租房、贷款新政
  12. 由于找不到vcruntime140_1.dll,无法继续执行代码
  13. H5通过数据流方式播放视频
  14. windows PC 连接Windows作为无线显示器
  15. 无脑安装教程:windows 10—QT5.9.5 + vs2013
  16. Java实习生常规技术面试题每日十题Java基础(五)
  17. PowerDesigner 15破解版下载
  18. 什么是Principle?能做什么?
  19. 下载并安装 Node
  20. vscode查看历史代码_VSCode中数据科学家的四大代码查看器

热门文章

  1. 无监督学习(2) 数据降维简述与Python实现
  2. [0 to 0.5]从零开始学习Android动画知识(下)
  3. el-upload 上传文件
  4. 基于卷积神经网络和SVM分类器的汽车识别-matlab
  5. oppor815t android 5,OPPOr815t
  6. React Native Autolinking 源码深入分析
  7. 动漫设计专业就业前景怎么样?
  8. “开源 · 开放 · 共享 · 创新” 「2022 木兰峰会」议程公布!
  9. 通过整理TCGA数据,探索某癌症的癌组织和正常组织的差异基因。
  10. Data Science三类职业方向:机器学习、数据分析和数据科学