
往常呼唤行独霸 ,呼唤绝对应的包的编制浩瀚呼唤行对象是提横跨产力的必备对象 ,鼠标可以让用户更随便上手,独霸降低用户进修成本 。斥地 而对斥地者,呼唤键盘独霸编制能较着汲引消辛苦,包的编制另有在一些专业对象中 ,独霸 除夜量独霸快捷键庖代繁琐的斥地鼠标独霸 ,可以使斥地人员愈加专注于工作,呼唤进步屈就,包的编制因为键盘独霸编制更随便产生发火肌肉记忆
举个栗子:我司营业研发,独霸前些年在我们的斥地强力鞭挞下(自愿)转向独霸了 git 作为版本独霸,最早独霸的呼唤是图形化“小乌龟”对象。后续展示几回问题措置起来较贫穷后,包的编制推荐其独霸原生的 git 呼唤行 。如今,独霸 git 呼唤行独霸版本独霸可谓 “一顿独霸猛如虎......”
呼唤行(键盘)独霸在很除夜程度上可以进步工作屈就 ,与之绝对应的是鼠标(触屏等)独霸,这两种编制是如今的主流人机交互编制
计整洁款呼唤行对象的斥地言语可以选择原始的 shell 、甚至是更原始的言语 C ,愈加随便上手且下场更多的有 node 、 python 、 golang
本文是基于 golang 斥地呼唤行对象的开篇,主假定基于 golang 原生内置的、轻量的 flag 包完成,用 golang 筹划呼唤行对象而不必 shell 、 python 的启事这里就不做叙说了
flag 包用来分析呼唤行参数
比照复杂的独霸 os.Args 来掉落踪掉落踪呼唤行参数, flag 可以完成屈就愈加通用的呼唤行用法 ,比如 mysql -u root -p 123456 。个中 mysql 是呼唤行的称号即这个呼唤 , -u 和 -p 分袂是这个呼唤的两个参数 :用户名和暗码 ,后背接着的是对应的参数值 ,有了参数的声明此后 ,两个参数可以交换职位 ,参数值也可以选填或屈就缺省(默许)值举办指定
flag 包支撑的呼唤行参数的圭表类型有 bool 、 int 、 int64 、 uint 、 uint64 、 float float64 、 string 、 duration
即布尔值 、整型、浮点型 、字符串 、时分段圭表类型
定义 flag 呼唤行参数,用来领受呼唤行输进的参数值,一样往常有以下两种编制
flag.TypeVar() :先定义参数(理论上是指针)
,再定义 flag.TypeVar 将呼唤行参数存储(绑定)到后面参数的值的指针(地址)
var name stringvar age intvar height float64var graduated bool// &name 就是领受用户呼唤行中输进的-n后背的参数值// 前去值是一个用来存储name参数的值的指针/地址// 定义string圭表类型呼唤行参数name,括号中按序是变量名、flag参数名、默许值 、参数声明flag.StringVar(&name, "n", "", "name参数,默许为空")// 定义整型呼唤行参数ageflag.IntVar(&age,"a", 0, "age参数,默许为0")// 定义浮点型呼唤行参数heightflag.Float64Var(&height,"h", 0, "height参数,默许为0")// 定义布尔型呼唤行参数graduatedflag.BoolVar(&graduated,"g", false, "graduated参数,默许为false")
flag.Type():用短变量声明的编拟定义参数圭表类型及变量名
// 定义string圭表类型呼唤行参数name,括号中按序是flag参数名、默许值、参数声明namePtr := flag.String("n", "", "name参数,默许为空")// 定义整型呼唤行参数ageage := flag.Int("a", 0, "age参数,默许为0")// 定义浮点型呼唤行参数heightheight := flag.Float64("h", 0, "height参数,默许为0")// 定义布尔型呼唤行参数graduatedgraduated:= flag.Bool("g", false, "graduated参数,默许为false")结实用法 ,定义好参数后 ,经由过程调用 flag.Parse() 来对呼唤行参数举办分析写进注册的 flag 里,进而分析掉落踪掉落踪参数值 ,经由过程搜检源码中也是调用的 os.Args
源码路途 go/src/flag/flag.go
// Parse parses the command-line flags from os.Args[1:]. Must be called// after all flags are defined and before flags are accessed by the program.func Parse() { // Ignore errors; CommandLine is set for ExitOnError. CommandLine.Parse(os.Args[1:])}进而搜检 Parse 编制的源码
func (f *FlagSet) Parse(arguments []string) error { f.parsed = true f.args = arguments for { seen, err := f.parseOne() if seen { continue } if err == nil { break } switch f.errorHandling { case ContinueOnError: return err case ExitOnError: if err == ErrHelp { os.Exit(0) } os.Exit(2) case PanicOnError: panic(err) } } return nil}真正分析参数的是 parseOne 编制(这里省略源码) ,结论是
分析参数时 ,对参数的指定编制一样往常有"-"、"--"、和可否空格等编制 ,组合上往有以下几种编制
| -flag *** | 空格和一个 - 标识表记标帜 |
|---|---|
| --flag *** | 空格和两个 - 标识表记标帜 |
| -flag=*** | 等号和一个 - 标识表记标帜 |
| --flag=*** | 等号和两个 - 标识表记标帜 |
个中, -flag *** 编制最为经常独霸,假定参数是布尔型 ,只能用等号编制指定
flag 包默许会屈就定义的呼唤行参数,在独霸时假定不输进参数就打印对应的辅佐信息
多么的辅佐信息我们可以对其举办袒护往改削默许的 Usage
package mainimport ( "flag" "fmt")func main() { var host string var port int var verbor bool var help bool // 绑定呼唤行参数与变量相干 flag.StringVar(&host, "H", "127.0.0.1", "ssh host") flag.IntVar(&port, "P", 22, "ssh port") flag.BoolVar(&verbor, "v", false, "detail log") flag.BoolVar(&help, "h", false, "help") // 自定义-h flag.Usage = func() { fmt.Println(`Usage: flag [-H addr] [-p port] [-v]Options: `) flag.PrintDefaults() } // 分析呼唤行参数 flag.Parse() if help { flag.Usage() } else { fmt.Println(host, port, verbor) }}/*➜ go run flag_args.go -hUsage: flag [-H addr] [-p port] [-v]Options: -H string ssh host (default "127.0.0.1") -P int ssh port (default 22) -h help -v detail log */复杂来讲,短参数和长参数,就是比如我们在独霸某些呼唤时 ,搜检呼唤版本可以输进 -V ,也可以输进 --version 。这类气候下, flag 并没有默许支撑,可是可以经由过程可以两个选项共享不合个变量来完成,即经由过程给某个不异的变量设置不合的选项,参数在初始化的时辰其按序是不结实的,是以还需求担保其具有不异的默许值
package mainimport ( "fmt" "flag")var logLevel stringfunc init() { const ( defaultLogLevel = "DEBUG" usage = "set log level" ) flag.StringVar(&logLevel, "log_level", defaultLogLevel, usage) flag.StringVar(&logLevel, "l", defaultLogLevel, usage + "(shorthand)")}func main() { flag.Parse() fmt.Println("log level:", logLevel)}经由过程 const 声明群众的常量,并在默许值和辅佐信息中往独霸,多么便可以完成了
完成筹算字符串或目次下递回筹算文件 md5 的呼唤 ,近似 linux 的 md5sum 呼唤
个中独霸 bufio 分批次读取文件,阻拦文件过除夜时构成成本占用高
package mainimport ( "bufio" "crypto/md5" "flag" "fmt" "io" "os" "strings")func md5reader(reader *bufio.Reader) string { // hasher := md5.New() // 定义MD5 hash筹算器 bytes := make([]byte, 1024*1024*10) // 分批次读取文件 for { n, err := reader.Read(bytes) if err != nil { if err != io.EOF { return "" } break } else { hasher.Write(bytes[:n]) } } return fmt.Sprintf("%x", hasher.Sum(nil))}func md5file(path string) (string, error) { file, err := os.Open(path) if err != nil { return "", err } else { defer file.Close() return md5reader(bufio.NewReader(file)), nil }}func md5str(txt string) (string, error) { return md5reader(bufio.NewReader(strings.NewReader(txt))), nil //return fmt.Sprintf("%x", md5.Sum([]byte(txt)))}func main() { txt := flag.String("s", "", "md5 txt") path := flag.String("f", "", "file path") help := flag.Bool("h", false, "help") flag.Usage = func() { fmt.Println(`Usage: md5 [-s 123abc] [-f path]Options: `) flag.PrintDefaults() } flag.Parse() if *help || *txt == "" && *path == "" { flag.Usage() } else { var md5 string var err error if *path != "" { md5, err = md5file(*path) } else { md5, err = md5str(*txt) } if err != nil { fmt.Println(err) } else { fmt.Println(md5) } }}编译生成二进制文件
➜ go build -o md5go -x md5_bufio.go➜ ll md5go -rwxr-xr-x 1 ssgeek staff 1.9M Oct 2 00:54 md5go
测试独霸
➜ ./md5go -h Usage: md5 [-s 123abc] [-f path]Options: -f string file path -h help -s string md5 txt➜ ./md5go -s 123456e10adc3949ba59abbe56e057f20f883e➜ ./md5go -f md5_bufio.go8607a07cbb98cec0e9abe14b0db0bee6
到此这篇关于Golang斥地呼唤行之flag包的独霸编制的文章就引见到这了,更多相干Go言语斥地呼唤行之flag包的独霸内容请搜刮完竣下载之前的文章或延续不雅不雅不雅不雅鉴赏上面的相干文章希看大年夜师往后多多支撑完竣下载!