精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一個庫,用Go搞定命令行程序

開發 前端
Go 官方有一個 flags 庫提供了最基礎的命令行參數支持,不過確實不好用,今天帶你認識一個超贊的庫——urfave/cli,它能讓你用一種簡單優雅的方式來構建命令行程序。

我們平時做的Go項目除了寫的各種API接口外,還經常會寫任務腳本、命令行程序、定時任務等,其實這幾個是一個東西,你寫的任務腳本支持接受指令傳參,那它不就是命令行程序了?再把程序部署到服務器用Go Cron加個任務就是定時任務了。

圖片圖片

Go 官方有一個 flags 庫提供了最基礎的命令行參數支持,不過確實不好用,今天帶你認識一個超贊的庫——urfave/cli,它能讓你用一種簡單優雅的方式來構建命令行程序。

什么是urfave/cli?

urfave/cli 是一個用 Go 編寫的、簡單、快速且有趣的庫,用于構建命令行應用程序。無論是小工具還是復雜的大型 CLI 程序,它都能輕松應對。它的設計哲學是讓我們用聲明式的方式來定義命令、子命令、標志(Flags),然后它會自動幫你處理參數解析、幫助文檔生成等所有繁瑣的工作,聽起來是不是很棒?

安裝

運行以下命令來安裝 urfave/cli 的 v2 版本:

go get github.com/urfave/cli/v2

第一個 CLI 程序

我們從經典的 "Hello, World!" 開始,創建一個 main.go 文件,然后敲入以下代碼:

package main

import (
    "log"
    "os"

    "github.com/urfave/cli/v2"
)

func main() {
    app := &cli.App{
        Name:  "greet",
        Usage: "向世界打個招呼!",
        Action: func(c *cli.Context) error {
            println("Hello, world!")
            returnnil
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}

運行命令程序

go run main.go

你會看到終端輸出了 Hello, world!,當然我們也可以 build 后用真正的命令去運行

# build
go build -o greet ./main.go 
# 運行命令
./greet

urfave/cli 自動為我們生成了幫助信息。上面這個命令運行時添加 --help 就能在控制臺輸出幫助信息。

添加命令行傳參

只會說 "Hello, world!" 可不夠,我們希望它能跟指定的人打招呼。這就要用到“標志”(Flags)了。

我們來修改一下代碼,添加一個 --name的標志:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/urfave/cli/v2"
)

func main() {
    app := &cli.App{
        Name:  "greet",
        Usage: "向世界或某人打個招呼!",
        Flags: []cli.Flag{
            &cli.StringFlag{
                Name:    "name",
                Value:   "world", // 默認值
                Usage:   "指定打招呼的對象",
                Aliases: []string{"n"}, // 別名,-n 等同于 --name
            },
        },
        Action: func(c *cli.Context) error {
            name := c.String("name")
            fmt.Printf("Hello, %s!\n", name)
            returnnil
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}

現在重新打包構建一下這個命令

$ go build -o greet ./main.go
# 不帶任何參數,使用默認值
$ ./greet
Hello, world!

# 使用 --name 標志
$ ./greet --name Gopher
Hello, Gopher!

# 使用別名 -n
$ ./greet -n 狗蛋
Hello, 狗蛋!

命令和子命令

當你的工具功能越來越復雜時,就需要引入“命令” 和 “子命令”來組織功能了。這就像 git 有 commit、push、pull 等子命令一樣。我們來模擬一個簡單的文件處理工具 filetool。

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/urfave/cli/v2"
)

func main() {
    app := &cli.App{
        Name:  "filetool",
        Usage: "一個簡單的文件處理工具",
        Commands: []*cli.Command{
            {
                Name:    "hash",
                Aliases: []string{"h"},
                Usage:   "計算文件的哈希值",
                Flags: []cli.Flag{
                    &cli.StringFlag{
                        Name:     "file",
                        Aliases:  []string{"f"},
                        Usage:    "指定輸入文件",
                        Required: true, // 這是一個必填項!
                    },
                },
                Action: func(c *cli.Context) error {
                    filePath := c.String("file")
                    // 這里的 hashFile 是我們自己實現的邏輯函數
                    fmt.Printf("正在為文件 '%s' 計算哈希...\n", filePath)
                    returnnil
                },
            },
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}

上面是添加了命令,對于復雜的命令行程序,尤其是在業務系統里用作處理數據的命令行程序,往往還需要子命令的支持。這樣我們可以把處理一個大類數據的任務都劃分到同一個命令下,每個細分任務在寫成命令的子命令。

下面是一個添加子命令的簡單例子:

var Word = &cli.Command{
 Name:    "word",
 Aliases: []string{"w"},
 Usage:   "Word文檔處理相關命令",
 Subcommands: []*cli.Command{
  {
   Name:  "parse",
   Usage: "解析Word文檔",
   Flags: []cli.Flag{
    &cli.StringFlag{
     Name:     "input",
     Aliases:  []string{"i"},
     Usage:    "輸入文件路徑",
     Required: true,
    },
    &cli.StringFlag{
     Name:     "output",
     Aliases:  []string{"o"},
     Usage:    "輸出文件路徑",
     Required: true,
    },
   },
   Action: func(c *cli.Context) error {
    return logic.NewWordLogic(c.Context).ParseWord(c.String("input"), c.String("output"))
   },
  },
 },
}

我們把這個子命令加到上面的

func main() {
    app := &cli.App{
        Name:  "filetool",
        Usage: "一個簡單的文件處理工具",
        Commands: []*cli.Command{
            // ......
            word,
            // 添加更多命令
        },
    }
    // ......
}

上面這個子命令的調用方式如下:

$ go build -o filetool ./main.go;
./filetool word parse -i input.docx -o output.txt

最佳實踐

基礎用法已經掌握了,但要構建一個健壯、可維護的命令行工具,我們還需要借鑒一些真實項目中的經驗。下面這些技巧,能讓你的代碼質量提升一個臺階。

鉤子函數:用 Before和 After統一處理邏輯

你可能希望在每個命令執行前后都做一些固定的操作,比如初始化日志、設置鏈路追蹤、上報監控數據或者記錄執行時間等。urfave/cli 提供了 Before 和 After 鉤子函數,來解決這個問題。

下面是我的專欄項目使用 urfave/cli 時添加的鉤子:

func main() {
 app := &cli.App{
  Name:  "gm-tools",
  Usage: "Go Mall 工具集",
  Before: func(c *cli.Context) error {
   // 為每個命令創建帶有追蹤信息的上下文
   ctx := context.Background()
   spanId := util.GenerateSpanID(util.GetLocalIP())
   ctx = context.WithValue(ctx, "spanid", spanId)
   c.Context = ctx

   cmdName := strings.Join(c.Args().Slice(), " ")
   logger.Info(ctx, fmt.Sprintf("定時任務【%s】開始執行. 時間=【%s】)", cmdName, time.Now().Format(enum.TimeFormatHyphenedYMDHIS)))
   returnnil
  },
  After: func(c *cli.Context) error {
   // 記錄執行的錯誤
   if c.Context.Err() != nil {
    logger.Error(c.Context, "定時任務執行失敗", c.Context.Err())
   }
   cmdName := strings.Join(c.Args().Slice(), " ")
   logger.Info(c.Context, fmt.Sprintf("定時任務【%s】執行完成. 時間=【%s", cmdName, time.Now().Format(enum.TimeFormatHyphenedYMDHIS)))
   returnnil
  },
  Commands: []*cli.Command{
   commands.Word,
   // 添加更多工具命令
  },
 }

if err := app.Run(os.Args); err != nil {
  log.Fatal(err)
 }
}

這樣無論你運行哪個命令,Before 和 After 里的日志都會被打印出來。更重要的是,我們將一個帶有追蹤信息的 Go context.Context 注入到了 cli.Context 中,在后續的 Action 函數里,我們可以通過 c.Context 取出這個上下文,并把它傳遞給業務邏輯,實現了全鏈路的追蹤!

責任編輯:武曉燕 來源: 網管叨bi叨
相關推薦

2023-03-31 08:44:55

Go開發命令

2016-03-28 10:00:09

Swift命令程序

2022-06-07 07:21:19

Python內置庫命令行

2010-07-15 10:58:23

Perl命令行程序

2019-04-16 06:50:34

2020-02-13 10:57:59

Python數據設計

2020-12-08 08:46:07

GoJava工具

2015-07-15 10:32:44

Node.js命令行程序

2022-09-23 09:50:45

Python

2022-09-27 13:07:41

clickPython命令行

2011-06-17 16:49:05

Cocoa蘋果

2018-06-12 15:10:11

Linuxvim命令PacVim

2019-06-10 15:00:27

node命令行前端

2023-10-30 01:00:42

Go語言Cobra庫

2018-11-21 09:57:44

命令行Linux文件

2016-08-10 12:41:00

Linux工具bcShell

2017-05-27 14:45:04

Linux命令進程

2022-02-17 18:21:47

工具HTTPie客戶端

2018-05-03 12:35:05

Linux命令Pet

2019-08-20 10:02:35

點贊
收藏

51CTO技術棧公眾號

天堂8在线天堂资源bt| 2018中文字幕一区二区三区| jizz18女人| 欧美人与禽性xxxxx杂性| 9i在线看片成人免费| 日韩美女激情视频| 久久久久久久久毛片| 伊人久久大香线蕉综合网蜜芽| 欧美日韩aaaaa| 亚洲熟妇av日韩熟妇在线| 福利成人在线观看| 成人免费观看男女羞羞视频| 国产精品吴梦梦| 在线观看亚洲天堂| 自拍偷拍欧美专区| 一区二区在线免费视频| 日韩精品人妻中文字幕有码| 欧美大片网站| 欧美性猛交xxxx免费看漫画 | 欧美视频网址| 精品国产精品网麻豆系列| 9l视频白拍9色9l视频| www成人免费观看| 亚洲日穴在线视频| 日韩中文一区| 日韩av资源站| 成人网页在线观看| 91传媒视频在线观看| 波多野结衣一区二区在线| 亚洲激情婷婷| 欧美片一区二区三区| 99热6这里只有精品| 欧美极品中文字幕| 精品视频在线播放免| 国产精品99精品无码视亚| 九九九精品视频| 在线观看视频一区二区欧美日韩| 久久黄色片视频| 欧美78videosex性欧美| 亚洲乱码日产精品bd| 中文字幕日韩精品久久| 在线观看完整版免费| 国产蜜臀97一区二区三区| 免费成人深夜夜行视频| 五月婷在线视频| 国产精品影视在线| 亚洲a成v人在线观看| 91tv国产成人福利| 久久国产精品色| 国产免费一区二区三区在线观看| 午夜视频网站在线观看| 日本亚洲最大的色成网站www| 欧美与欧洲交xxxx免费观看| av大片免费观看| 一本色道久久综合亚洲精品高清| 久久久日本电影| 日韩成人免费在线视频| 一本久久知道综合久久| 国产91免费看片| 国产一级片一区二区| 美女免费视频一区| 成人黄色av网| 精品二区在线观看| 高清av一区二区| 精品免费日产一区一区三区免费| 视频三区在线观看| 久久久久久黄色| 亚洲欧洲精品在线| 国产精品久久麻豆| 亚洲综合精品久久| ww国产内射精品后入国产| xx欧美xxx| 欧美无砖专区一中文字| 一区二区在线免费看| 国产视频一区二区在线播放| 欧美大肚乱孕交hd孕妇| 中文字幕影片免费在线观看| 国产亚洲一区| yellow中文字幕久久| 久草视频在线资源| 嫩草成人www欧美| 国产欧美日韩丝袜精品一区| 国产黄色免费大片| 久久嫩草精品久久久久| 一区二区三区四区视频在线| 青草av在线| 色婷婷精品大在线视频| 日韩av片免费观看| 国产欧美自拍一区| 中文字幕精品—区二区| 九九热最新地址| 亚洲欧美日韩国产综合精品二区| 国产欧美日韩综合精品| 日韩一区二区三区在线观看视频| 欧美激情一区在线观看| 日韩精品免费一区| 欧美精品总汇| 欧美α欧美αv大片| 国产免费无遮挡吸奶头视频| 国产精品久久| 国产精品女人网站| 日韩一级免费毛片| 中文字幕中文字幕一区| 内射国产内射夫妻免费频道| 亚洲日韩中文字幕一区| 亚洲久久久久久久久久| avove在线播放| 奇米色一区二区三区四区| 国产区二精品视| 毛片在线看片| 91福利国产成人精品照片| 精品人妻一区二区免费| 欧美3p在线观看| 欧美中文字幕在线观看| 亚洲精品国产精| 国产精品理伦片| 欧美精品一区二区三区免费播放| 51vv免费精品视频一区二区| 日韩在线一区二区三区免费视频| 9i精品福利一区二区三区| 国产·精品毛片| 国产精品一区在线免费观看| 日韩一区精品| 亚洲视频一区二区三区| 国产成人免费看| 成人精品免费网站| 91嫩草国产丨精品入口麻豆| 羞羞视频在线观看一区二区| 中文字幕国产亚洲2019| 亚洲欧美日韩激情| 91色在线porny| 91免费黄视频| 亚洲一区二区免费在线观看| 久久在线观看视频| 一道本无吗一区| 国产精品久久毛片av大全日韩| 日本成人在线免费视频| 九九综合在线| 欧美在线国产精品| 色资源在线观看| 精品久久久久久| 91视频啊啊啊| 一本色道88久久加勒比精品| 精品蜜桃传媒| 成人福利av| 亚洲人成网在线播放| 精品免费囯产一区二区三区| 久久一夜天堂av一区二区三区| 国产白丝袜美女久久久久| 国内露脸中年夫妇交换精品| 性欧美亚洲xxxx乳在线观看| 神马午夜精品95| 欧美日韩国产丝袜美女| 中文字字幕码一二三区| 巨乳诱惑日韩免费av| 日韩av高清在线播放| 亚洲四虎影院| 久久艳片www.17c.com| 国产v片在线观看| 艳妇臀荡乳欲伦亚洲一区| 成人在线观看一区二区| 日韩视频二区| 免费看污久久久| 素人啪啪色综合| 久久精品一本久久99精品| www.色播.com| 黄色精品在线看| 欧美色图亚洲激情| 欧美aaaaa成人免费观看视频| 一区二区免费在线观看| 亚洲国产精品免费视频| 国模吧一区二区| 免费国产在线观看| 欧美日韩国产一级| 久久国产精品二区| 26uuu色噜噜精品一区| 国内自拍视频网| 欧美在线91| 九九99久久| 伦一区二区三区中文字幕v亚洲| 久久香蕉国产线看观看网| 懂色av蜜臀av粉嫩av分享吧| 日韩欧美999| 欧美日韩色视频| 99久久综合狠狠综合久久| 久久精品免费网站| 亚洲一级一区| 欧美日韩免费高清| 精品一区二区三区视频在线播放| 69久久夜色精品国产69乱青草| www亚洲人| 亚洲精品国产suv| 一区二区日韩在线观看| 午夜久久久久久| 日本激情视频一区二区三区| 99国产麻豆精品| 一区二区久久精品| 久久精品盗摄| 久久久久久久久久伊人| 欧美三级三级| 国产一区二区免费电影| 亚洲一区有码| 日本中文字幕久久看| 欧美另类tv| 日韩在线播放av| 日本在线视频1区| 欧美va天堂va视频va在线| 伊人成人在线观看| 黑人巨大精品欧美一区二区一视频 | 亚洲精品少妇一区二区| 亚洲人成精品久久久| 99久久自偷自偷国产精品不卡| 日韩制服一区| 欧美又大粗又爽又黄大片视频| 在线观看中文| 最新的欧美黄色| 麻豆app在线观看| 日韩精品影音先锋| 国产精品久久久午夜夜伦鲁鲁| 欧美性色xo影院| 狠狠躁夜夜躁人人爽天天高潮| 亚洲人xxxx| 中文字幕91视频| 久久精品亚洲一区二区三区浴池| av av在线| 国产成人亚洲精品青草天美 | 99久久精品情趣| 精品伦一区二区三区| 国产一区视频在线看| 不卡av免费在线| 久久一区亚洲| 欧美精品一区二区三区免费播放| 亚洲一区黄色| 精品这里只有精品| 亚洲精品人人| 精品无码国模私拍视频| www.爱爱.com| 国产一区二区在线观看免费| 成人在线看视频| 9国产精品视频| 欧美午夜性视频| 国产字幕视频一区二区| 色乱码一区二区三区熟女| 日韩久久电影| 亚洲一区精品视频| 成人高清av| 在线观看日韩羞羞视频| 91综合久久一区二区| av在线精品| 国产综合在线视频| 俺来也官网欧美久久精品| 久久久久久18| aa视频在线观看| 91干在线观看| 免费成人美女女| 国产精品xxx视频| 日韩一级特黄| 亚洲一区亚洲二区亚洲三区| 日韩精品一级| 国产一区二区高清视频| 蜜桃tv一区二区三区| 日韩免费电影一区二区| 日韩精品永久网址| 50度灰在线观看| 亚洲人成久久| 国产1区2区在线| 免费美女久久99| 爱情岛论坛亚洲自拍| 成人精品视频一区二区三区 | 网曝91综合精品门事件在线 | 伊人情人综合网| 日本人妻伦在线中文字幕| 中文在线一区| 五月婷婷六月合| 成人综合在线视频| 草草影院第一页| 亚洲欧洲色图综合| 国产在线视频二区| 色综合欧美在线视频区| 91国在线视频| 亚洲成人网在线| 国产理论电影在线观看| 不用播放器成人网| 在线播放高清视频www| 国产美女精品视频| 激情视频极品美女日韩| 日韩视频精品| 国产精品v一区二区三区| 男人亚洲天堂网| 国产真实乱子伦精品视频| 日本japanese极品少妇| 国产精品福利在线播放| 日韩少妇高潮抽搐| 欧美日韩一本到| 日本黄色免费视频| 色婷婷综合久久久久| 激情国产在线| 亚洲xxxxx性| 日韩成人免费| 1024av视频| 国产乱码精品一区二区三区av| 欧美激情aaa| 亚洲国产精品久久一线不卡| 免费看av在线| 日韩精品免费视频| 在线你懂的视频| 国产精品自在线| 亚洲三级精品| 欧美日韩福利在线| 久久爱另类一区二区小说| 中文字幕5566| 亚洲国产cao| 精品国产无码一区二区三区| 中文字幕在线日韩| 暖暖成人免费视频| 亚洲精品福利在线| 欧美黄网站在线观看| 奇米精品一区二区三区在线观看一| 波多野结衣加勒比| 一区二区在线看| 91肉色超薄丝袜脚交一区二区| 亚洲欧洲av一区二区| 91超碰国产在线| 国产成人看片| 欧美日韩综合| 国产黄色一区二区三区| 中文字幕一区二区在线观看| 免费无码国产精品| 亚洲男人的天堂网站| 国产无遮挡裸体视频在线观看| 99伊人久久| 欧美一区二区三区另类| 成人av毛片在线观看| 国产精品久久福利| 伊人影院中文字幕| 夜夜嗨av色一区二区不卡| 欧美xxx网站| 欧美激情专区| 久久婷婷av| 免费污网站在线观看| 欧美性猛交xxxx乱大交退制版| 精品久久av| 国产精品99久久99久久久二8| 精品久久视频| 亚洲 欧美 日韩系列| 国产精品水嫩水嫩| 中文字幕在线观看精品| 色婷婷av一区二区三区在线观看| 亚洲免费资源| 久久久久久久香蕉| 成人午夜伦理影院| 亚洲日本韩国在线| 亚洲女人天堂网| 播放一区二区| 免费看啪啪网站| 国产精品一区久久久久| 国产第一页在线播放| 亚洲美女av电影| 成人全视频在线观看在线播放高清 | 午夜精品久久17c| 婷婷五月色综合香五月| 久久午夜夜伦鲁鲁一区二区| 国产精品免费人成网站| 国产男女无套免费网站| 欧美激情在线观看视频| 图片婷婷一区| 亚洲精品午夜在线观看| 亚洲精品v日韩精品| 天堂在线视频观看| 国产精品18久久久久久麻辣| 国产电影一区二区在线观看| 无码人妻一区二区三区精品视频 | 伊人成色综合网| 中文字幕欧美国产| 精品久久久无码中文字幕| 亚州精品天堂中文字幕| 精品国产91| 台湾佬美性中文| 色综合久久综合中文综合网| 黄色免费在线看| 精品乱子伦一区二区三区| 蜜臀va亚洲va欧美va天堂| 久草免费在线观看视频| 亚洲视频在线看| 亚洲精品在线国产| 男人舔女人下面高潮视频| 亚洲欧美另类久久久精品| 天天综合网在线| 成人信息集中地欧美| 亚洲免费中文| 中文字幕在线有码| 日韩久久午夜影院| 国内不卡的一区二区三区中文字幕 | 成人免费视频网站入口::| 精品五月天久久| 少妇精品在线| 亚洲欧美自偷自拍另类| 五月天网站亚洲| 最新超碰在线| 亚洲高清资源综合久久精品|