日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go语言命令行库urfave/cli简介

發布時間:2025/3/21 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go语言命令行库urfave/cli简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多用Go寫的命令行程序都用了urfave/cli這個庫,包括geth,有必要簡單了解一下。

用C寫過命令行程序的人應該都不陌生,我們需要根據argc/argv一個個地解析命令行參數,調用不同的函數,最后還要寫一個usage()函數用于打印幫助信息。urfave/cli把這個過程做了一下封裝,抽象出flag/command/subcommand這些模塊,用戶只需要提供一些模塊的配置,參數的解析和關聯在庫內部完成,幫助信息也可以自動生成。

舉個例子,我們想要實現下面這個命令行程序:

NAME:GoTest - hello worldUSAGE:GoTest [global options] command [command options] [arguments...]VERSION:1.2.3COMMANDS:help, h ?Shows a list of commands or help for one commandarithmetic:add, a ?calc 1+1sub, s ?calc 5-3database:db ?database operationsGLOBAL OPTIONS:--lang FILE, -l FILE ? ?read from FILE (default: "english")--port value, -p value ?listening port (default: 8000)--help, -h ? ? ? ? ? ? ?Help!Help!--print-version, -v ? ? print version


1. 基本結構
導入包以后,通過cli.NewApp()創建一個實例,然后調用Run()方法就實現了一個最基本的命令行程序了。

當然,為了讓我們的程序干點事情,可以指定一下入口函數app.Action,具體寫法如下:

?import ("fmt""gopkg.in/urfave/cli.v1" )func main() {app := cli.NewApp()app.Action = func(c *cli.Context) error {fmt.Println("BOOM!")return nil}err := app.Run(os.Args)if err != nil {log.Fatal(err)} }


2. 公共配置
就是幫助里需要顯示的一些基本信息:

??

?app.Name = "GoTest"app.Usage = "hello world"app.Version = "1.2.3"


3. Flag配置
具體對應于幫助中的以下信息:

? ?

--lang FILE, -l FILE ? ?read from FILE (default: "english") --port value, -p value ?listening port (default: 8000)


對應代碼:

?? ?

var language stringapp.Flags = []cli.Flag {cli.IntFlag {Name: "port, p",Value: 8000,Usage: "listening port",},cli.StringFlag {Name: "lang, l",Value: "english",Usage: "read from `FILE`",Destination: &language,},}


可以看到,每一個flag都對應一個cli.Flag接口的實例。

Name字段中逗號后面的字符表示flag的簡寫,也就是說"--port"和"-p"是等價的。

Value字段可以指定flag的默認值。

Usage字段是flag的描述信息。

Destination字段可以為該flag指定一個接收者,比如上面的language變量。解析完"--lang"這個flag后會自動存儲到這個變量里,后面的代碼就可以直接使用這個變量的值了。

另外,如果你想給用戶增加一些屬性值類型的提示,可以通過占位符(placeholder)來實現,比如上面的"--lang FILE"。占位符通過``符號來標識。

我們可以在app.Action中測試一下打印這些flag的值:

?? ?

app.Action = func(c *cli.Context) error {fmt.Println("BOOM!")fmt.Println(c.String("lang"), c.Int("port"))fmt.Println(language)return nil}


另外,正常來說幫助信息里的flag是按照代碼里的聲明順序排列的,如果你想讓它們按照字典序排列的話,可以借助于sort:

import "sort" sort.Sort(cli.FlagsByName(app.Flags))

最后,help和version這兩個flag有默認實現,也可以自己改:

?cli.HelpFlag = cli.BoolFlag {Name: "help, h",Usage: "Help!Help!",}cli.VersionFlag = cli.BoolFlag {Name: "print-version, v",Usage: "print version",}


4. Command配置
命令行程序除了有flag,還有command(比如git log, git commit等等)。

另外每個command可能還有subcommand,也就必須要通過添加兩個命令行參數才能完成相應的操作。比如我們的db命令包含2個子命令,如果輸入GoTest db -h會顯示下面的信息:

NAME:GoTest db - database operationsUSAGE:GoTest db command [command options] [arguments...]COMMANDS:insert ?insert datadelete ?delete dataOPTIONS:--help, -h ?Help!Help!


每個command都對應于一個cli.Command接口的實例,入口函數通過Action指定。如果你想像在幫助信息里實現分組顯示,可以為每個command指定一個Category。具體代碼如下:

?app.Commands = []cli.Command {{Name: "add",Aliases: []string{"a"},Usage: "calc 1+1",Category: "arithmetic",Action: func(c *cli.Context) error {fmt.Println("1 + 1 = ", 1 + 1)return nil},},{Name: "sub",Aliases: []string{"s"},Usage: "calc 5-3",Category: "arithmetic",Action: func(c *cli.Context) error {fmt.Println("5 - 3 = ", 5 - 3)return nil},},{Name: "db",Usage: "database operations",Category: "database",Subcommands: []cli.Command {{Name: "insert",Usage: "insert data",Action: func(c *cli.Context) error {fmt.Println("insert subcommand")return nil},},{Name: "delete",Usage: "delete data",Action: func(c *cli.Context) error {fmt.Println("delete subcommand")return nil},},},},}


如果你想在command執行前后執行后完成一些操作,可以指定app.Before/app.After這兩個字段:

app.Before = func(c *cli.Context) error {fmt.Println("app Before")return nil}app.After = func(c *cli.Context) error {fmt.Println("app After")return nil}


具體測試一下:

$ GoTest add $ GoTest db insert


5. 小結
總體來說,urfave/cli這個庫還是很好用的,完成了很多routine的工作,程序員只需要專注于具體業務邏輯的實現。

附完整demo代碼:

package cliimport ("fmt""os""log""sort""gopkg.in/urfave/cli.v1" )func Run() {var language stringapp := cli.NewApp()app.Name = "GoTest"app.Usage = "hello world"app.Version = "1.2.3"app.Flags = []cli.Flag {cli.IntFlag {Name: "port, p",Value: 8000,Usage: "listening port",},cli.StringFlag {Name: "lang, l",Value: "english",Usage: "read from `FILE`",Destination: &language,},}app.Commands = []cli.Command {{Name: "add",Aliases: []string{"a"},Usage: "calc 1+1",Category: "arithmetic",Action: func(c *cli.Context) error {fmt.Println("1 + 1 = ", 1 + 1)return nil},},{Name: "sub",Aliases: []string{"s"},Usage: "calc 5-3",Category: "arithmetic",Action: func(c *cli.Context) error {fmt.Println("5 - 3 = ", 5 - 3)return nil},},{Name: "db",Usage: "database operations",Category: "database",Subcommands: []cli.Command {{Name: "insert",Usage: "insert data",Action: func(c *cli.Context) error {fmt.Println("insert subcommand")return nil},},{Name: "delete",Usage: "delete data",Action: func(c *cli.Context) error {fmt.Println("delete subcommand")return nil},},},},}app.Action = func(c *cli.Context) error {fmt.Println("BOOM!")fmt.Println(c.String("lang"), c.Int("port"))fmt.Println(language)// if c.Int("port") == 8000 {// ?? ?return cli.NewExitError("invalid port", 88)// }return nil}app.Before = func(c *cli.Context) error {fmt.Println("app Before")return nil}app.After = func(c *cli.Context) error {fmt.Println("app After")return nil}sort.Sort(cli.FlagsByName(app.Flags))cli.HelpFlag = cli.BoolFlag {Name: "help, h",Usage: "Help!Help!",}cli.VersionFlag = cli.BoolFlag {Name: "print-version, v",Usage: "print version",}err := app.Run(os.Args)if err != nil {log.Fatal(err)} }


---------------------?
作者:turkeycock?
來源:CSDN?
原文:https://blog.csdn.net/TurkeyCock/article/details/80359654?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的Go语言命令行库urfave/cli简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。