广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang实现简易的命令行功能
  • 376
分享到

Golang实现简易的命令行功能

Golang实现命令行功能Golang命令行功能Golang命令行 2023-02-13 12:02:58 376人浏览 安东尼
摘要

目录前言开始flag.Stringflag.Intflag.StringVarflag.IntVar定义命令行参数实现 -f -v 是否强制拷贝copyFileAction 实现co

前言

一次偶然的想法,想知道为什么在终端输入那些命令行后,就执行了对应的操作,这转化为代码,应该怎么实现呢?

既然有了问题,那我们就来解决问题吧!

首先我认为想做命令行操作,那就得先”认识“命令行(当然这里指你的代码认识),所以我认位有两个步骤:

  • 解析命令行
  • 实现对应命令行的功能

话不多说开干!

开始

正好在学习 golang ,那就用它的试试吧!

首先,我们先来学习以下几个 api

flag.String

// String defines a string flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
// String 定义了一个字符串标志,具有指定的名称、默认值和用法字符串。返回值是存储标志值的字符串变量的地址。
func String(name string, value string, usage string) *string {
	return CommandLine.String(name, value, usage)
}

也就是说,使用-name value 的命令参数,usage是对这个参数的说明,返回值是这个 value 的指针,也就是用户输入在 -name 后的 value

flag.Int

// Int defines an int flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
// Int 定义了一个具有指定名称、默认值和用法字符串的 int 标志。返回值是存储标志值的 int 变量的地址。
func Int(name string, value int, usage string) *int {
	return CommandLine.Int(name, value, usage)
}

使用方式和 String() 一样,只是类型的区别。

flag.StringVar

// StringVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a string variable in which to store the value of the flag.
// StringVar 定义了一个带有指定名称、默认值和用法字符串的字符串标志。参数 p 指向一个字符串变量,用于存储标志的值。
func StringVar(p *string, name string, value string, usage string) {
	CommandLine.Var(newStringValue(value, p), name, usage)
}

这里可以看到区别就是,将返回值指针,变成了函数的第一个参数。

flag.IntVar

// IntVar defines an int flag with specified name, default value, and usage string.
// The argument p points to an int variable in which to store the value of the flag.
// IntVar 定义了一个具有指定名称、默认值和用法字符串的 int 标志。参数 p 指向一个存储标志值的 int 变量。
func IntVar(p *int, name string, value int, usage string) {
	CommandLine.Var(newIntValue(value, p), name, usage)
}

了解这些后,我们就开始吧!

定义命令行参数

package main

// ...import

func commandStyle() {
	methodPtr := flag.String("method", "default", "method of sample")
	valuePtr := flag.Int("value", -1, "value of sample")

	// 解析
	flag.Parse()
	fmt.Println(*methodPtr, *valuePtr)
}

func commandStyle2() {
	var method string
	var value int
	flag.StringVar(&method, "method", "default", "method of sample")
	flag.IntVar(&value, "value", -1, "value of sample")
	flag.Parse()
	fmt.Println(method, value)
}

func main() {
	commandStyle()
}

在终端使用 Go run . -method get -value 1 这串命令后,打印出了 get 1

Parse 解析来自 os.Args[1:] 的命令行标志。必须在定义所有标志之后和程序访问标志之前调用。

这里的一个重要的点就是要使用 flag.Parse(),也就是解析go run .` 之后的标志。使用变量将标志的值接收,然后打印。

这两种方式结果都是一样,只有写法上的差距,这时候虽然我们体验了一点简单的命令行的影子了,但似乎还是感觉好像啥效果也没有呀。接下来我们就来实现一个 copy 文件内容的功能

实现 -f -v 是否强制拷贝

首先我们使用上面说过的类似方式,注册标志 f,v,然后解析标志

func main() {
    var showProgress, force bool
	// -f 当存在时拷贝,是否强制拷贝
	flag.BoolVar(&force, "f", false, "force copy when existing")
	flag.BoolVar(&showProgress, "v", false, "explain what is being done")
	flag.Parse()

	// 获取参数个数,必须要输入两个参数,因为copy是从这个文件到另一个文件
	if flag.NArg() < 2 {
		flag.Usage() // 打印用途
		return
	}
    copyFileAction(flag.Arg(0), flag.Arg(1), showProgress, force)
}

注册标志完成后,我们就可以开始实现我们的 copy 功能了

首先我们必须后面要输入两个文件名,让最后一个文件copy到前一个文件(制定规则)

我们模拟命令行输入:go run . -f -v a.txt b.txt ,这就是我们最后需要实现的东西,f, v是可以省略的,默认把 a.txt -> b.txt

  • -f表示当文件存在时,强制copy覆盖里面的内容
  • -v表示解释正在做什么

接下来我们需要实现一个 copyFileAction 函数,来实现copy功能,以及命令行参数的效果

copyFileAction 实现

func fileExist(fileName string)bool {
	_, err := os.Stat(fileName) // 返回这个文件信息
	// IsExist 只是错误或报告是否存在
	// err == nil,表示有文件信息,os.IsExist(err),表示有文件存在
	return err == nil || os.IsExist(err)
}

// 转化操作,命令行,与功能实现的逻辑判断
func copyFileAction(src, dst string, showProgress, force bool) {
	if !force {
		// 判断是否存在文件,若存在,是否需要覆盖它
		if fileExist(dst) {
			fmt.Printf("%s exists override? y/n \n", dst)
			reader := bufio.NewReader(os.Stdin) // 读取输入内容
			data, _, _ := reader.ReadLine() // 取一行的内容
			// 判断输入的内容
			if strings.TrimSpace(string(data)) != "y" {
				return
			}
		}
	}
    // copy 文件
	copyFile(src, dst)
}

这里我们可以看到充分利用到了 showProgress 和 force 两个命令行取的值,当文件``存在且不强制`时,会有一个询问,是否覆盖,同意就实行 copy 操作,不同意不做处理(相当于一次无效命令)。

接下来我们实现功能核心 copyFile

copyFile

func copyFile(originFile, targetFile string)(written int64, err error){
	srcFile, err := os.Open(originFile) // 打开文件
	if err != nil {
		// Error() 返回错误信息
		log.Fatal(err)
		return
	}
	defer srcFile.Close()
	dstFile, err := os.Create(targetFile) // 创建文件
	if err != nil {
		// Error() 返回错误信息
		log.Fatal(err)
		return
	}
	defer dstFile.Close()
	return io.Copy(dstFile, srcFile) // 拷贝文件
}

这里我们是采取,将需要被拷贝的文件打开,拷贝到的文件名进行创建,然后将内容填充进去,这里使用了io.Copy() 的内置功能。

效果图

完整代码

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

// func commandStyle() {
// 	methodPtr := flag.String("method", "default", "method of sample")
// 	valuePtr := flag.Int("value", -1, "value of sample")

// 	// 解析
// 	flag.Parse()
// 	fmt.Println(*methodPtr, *valuePtr)
// }

// func commandStyle2() {
// 	var method string
// 	var value int
// 	flag.StringVar(&method, "method", "default", "method of sample")
// 	flag.IntVar(&value, "value", -1, "value of sample")
// 	flag.Parse()
// 	fmt.Println(method, value)
// }

func main() {
	// commandStyle()
	// commandStyle2()
	var showProgress, force bool
	// -f 当存在时拷贝,是否强制拷贝
	flag.BoolVar(&force, "f", false, "force copy when existing")
	flag.BoolVar(&showProgress, "v", false, "explain what is being done")
	flag.Parse()

	// 获取参数个数
	if flag.NArg() < 2 {
		flag.Usage() // 打印用途
		return
	}
	copyFileAction(flag.Arg(0), flag.Arg(1), showProgress, force)
}

func fileExist(fileName string)bool {
	_, err := os.Stat(fileName) // 返回这个文件信息
	// IsExist 只是错误或报告是否存在
	// err == nil,表示有文件信息,os.IsExist(err),表示有文件存在
	return err == nil || os.IsExist(err)
}

func copyFile(originFile, targetFile string)(written int64, err error){
	srcFile, err := os.Open(originFile) // 打开文件
	if err != nil {
		// Error() 返回错误信息
		log.Fatal(err)
		return
	}
	defer srcFile.Close()
	dstFile, err := os.Create(targetFile) // 创建文件
	if err != nil {
		// Error() 返回错误信息
		log.Fatal(err)
		return
	}
	defer dstFile.Close()
	return io.Copy(dstFile, srcFile) // 拷贝文件
}

// 拷贝文件
func copyFileAction(src, dst string, showProgress, force bool) {
	if !force {
		// 判断是否存在文件,若存在,是否需要覆盖它
		if fileExist(dst) {
			fmt.Printf("%s exists override? y/n \n", dst)
			reader := bufio.NewReader(os.Stdin) // 读取输入内容
			data, _, _ := reader.ReadLine() // 取一行的内容
			// 判断输入的内容
			if strings.TrimSpace(string(data)) != "y" {
				return
			}
		}
	}
	// copy 文件
	copyFile(src, dst)
}

以上就是Golang实现简易的命令行功能的详细内容,更多关于Golang命令行功能的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: Golang实现简易的命令行功能

本文链接: https://www.lsjlt.com/news/195818.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang实现简易的命令行功能
    目录前言开始flag.Stringflag.Intflag.StringVarflag.IntVar定义命令行参数实现 -f -v 是否强制拷贝copyFileAction 实现co...
    99+
    2023-02-13
    Golang实现命令行功能 Golang命令行功能 Golang命令行
  • golang实现命令行程序的使用帮助功能
    通过flag包我们可以很方便的实现命令行程序的参数标志,接下来我们来看看如何实现命令行程序的使用帮助,通常以参数标志-h或--help的形式来使用。 自动生成使用帮助 我们只需要声明...
    99+
    2022-11-13
  • golang执行命令行的实现
    一般情况下,在 golang 中执行一些命令如 git clone,则可以使用 exec.Command 函数 func RunCommand(path, name string, ...
    99+
    2022-11-11
  • golang简易令牌桶算法实现代码
    基本思路:定义一个chan,chan大小为需要限制的qps大小,go一个协程启动tick,每1000/qps时间在tick中写入数值,启动另一个协程,读取chan中的值,如果读取到c...
    99+
    2022-11-12
  • Android实现简易的闹钟功能
    本文实例为大家分享了Android实现简易的闹钟功能的具体代码,供大家参考,具体内容如下 主要是通过广播,实现一个闹钟的简易功能。 实现效果如下: 主界面为一个简易的设置闹钟Butt...
    99+
    2022-11-13
  • java实现简易聊天功能
    本文实例为大家分享了java实现简易聊天功能的具体代码,供大家参考,具体内容如下 应用客户端和服务端通过控制台的输入输出实现简易聊天功能 思路: 1.创建服务端类ChatServer...
    99+
    2022-11-13
  • Android实现简易计算功能
    本文实例为大家分享了Android实现简易计算功能的具体代码,供大家参考,具体内容如下 效果如图: activity_main.xml <?xml version...
    99+
    2022-11-12
  • C#实现简易点餐功能
    本文实例为大家分享了C#实现简易点餐功能的具体代码,供大家参考,具体内容如下 图示效果 实现过程 1.设计界面 2.设计控件及其属性 3.实现点击事件、显示事件以及运算 4实现功能...
    99+
    2022-11-12
  • Android实现简易秒表功能
    本文实例为大家分享了Android实现秒表功能的具体代码,供大家参考,具体内容如下 今天为了给师弟们讲安卓,花了10分钟写了一个简易的秒表app,现贴出代码,供各位刚入门以及还未入...
    99+
    2022-11-13
  • Golang实现简易的rpc调用
    目录开始实现两点之间的通讯(transport)实现反射调用已注册的方法总结(自我pua)RPC(Remote Procedure Call Protocol)远程过程调用协议。 一...
    99+
    2023-03-06
    Golang实现rpc调用 Golang rpc调用 Golang rpc
  • vue实现简易的计算器功能
    本文实例为大家分享了vue实现简易计算器功能的具体代码,供大家参考,具体内容如下 实现功能:将两个输入框中的值进行加减乘除计算 用到的知识点: 1.v-model数据双向绑定 2. ...
    99+
    2022-11-12
  • Java实现简易的分词器功能
    业务需求: 生活中常见的搜索功能大概可分为以下几类: 单关键词。如“Notebook” 双关键词加空格。如“Super Notebook” 多关键词加多空格...
    99+
    2022-11-12
  • javascript实现简易的计算器功能
    本文实例为大家分享了javascript实现简易的计算器的具体代码,供大家参考,具体内容如下 javascript实现简易计算器,只有两个input输入框,简单实现加减乘除: <...
    99+
    2022-11-13
  • Androidstudio实现简易的计算器功能
    本文实例为大家分享了android studio简易运算器,供大家参考,具体内容如下 JAVA语句代码块: package com.example.douyingming; im...
    99+
    2022-11-13
  • C++实现简易通讯录功能
    目录实现功能一、定义通讯录和通讯录人员结构体二、实现通讯录输入菜单1.定义菜单函数:2.主函数循环体中循环展示菜单信息三、实现增删改查和清空通讯录功能四、运行截图展示本文实例为大家分...
    99+
    2022-11-13
  • C++实现简易计算器功能
    本文实例为大家分享了C++实现简易计算器功能的具体代码,供大家参考,具体内容如下 介绍 介绍:仅支持自然数间的+ - * /操作,并没有括号。 实现:利用栈实现存储运算数以及运算符。...
    99+
    2022-11-13
  • jQuery实现简易计算器功能
    jQuery制作一个简易计算器,供大家参考,具体内容如下 页面效果: 源码: <!DOCTYPE html> <html> <head>    ...
    99+
    2022-11-13
  • SpringMvc实现简易计算器功能
    用SpringMvc做一个简易计算器,供大家参考,具体内容如下 一 .domain类 package ssm1.domain; public class JiSuan {     ...
    99+
    2022-11-13
  • Pyqt实现简易计算器功能
    本文实例为大家分享了Pyqt实现简易计算器的具体代码,供大家参考,具体内容如下 环境:pycharm、python3.7 首先用qtDesigner设计出如下界面。 再用pyUIC...
    99+
    2022-11-10
  • java方法实现简易ATM功能
    用java方法写简易ATM,供大家参考,具体内容如下 本文需求:用java写一个简易ATM 功能:有登陆,有查询资金功能,有存款功能,有取款功能,有转账功能,有退出; 简述: (ja...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作