欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言命令行參數(shù)及cobra使用方法

 更新時(shí)間:2024年01月09日 09:23:48   作者:世界盡頭與你  
Cobra是關(guān)于golang的一個(gè)命令行解析庫(kù),用它能夠快速創(chuàng)建功能強(qiáng)大的 cli應(yīng)用程序和命令行工具,本文主要介紹了Go語(yǔ)言命令行參數(shù)及cobra使用方法,感興趣的可以了解一下

1.原生命令行參數(shù)

os 包以跨平臺(tái)的方式,提供了一些與操作系統(tǒng)交互的函數(shù)和變量。程序的命令行參數(shù)可從 os 包的 Args 變量獲??;os 包外部使用 os.Args 訪問(wèn)該變量

os.Args 變量是一個(gè)字符串(string)的 切片(slice),os.Args 的第一個(gè)元素:os.Args[0],是命令本身的名字;其它的元素則是程序啟動(dòng)時(shí)傳給它的參數(shù)

func main() {
	var s, sep string
	for i := 1; i < len(os.Args); i++ {
		s += sep + os.Args[i]
		sep = " "
	}
	fmt.Println(s)
}

執(zhí)行程序,會(huì)輸出所有參數(shù),以空格做分割:

go run hello.go 1 2.1 nma

2.使用CIL框架Cobra

cobra

Cobra 應(yīng)用程序?qū)⒆裱韵陆M織結(jié)構(gòu):

? appName/
  ? cmd/
      add.go
      your.go
      commands.go
      here.go
    main.go

創(chuàng)建 rootCmd

Cobra 不需要任何特殊的構(gòu)造函數(shù)。只需創(chuàng)建命令即可

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	cfgFile     string // 配置文件路徑
	userLicense string // 許可證類型

	rootCmd = &cobra.Command{
		// 應(yīng)用名稱
		Use: "cobra-cli",
		// 應(yīng)用簡(jiǎn)短描述
		Short: "A generator for Cobra based Applications",
		// 應(yīng)用詳細(xì)描述
		Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	}
)

// Execute 用于執(zhí)行根命令 rootCmd
func Execute() error {
	return rootCmd.Execute()
}

func init() {
	// 在執(zhí)行任何子命令之前調(diào)用 initConfig() 函數(shù)
	cobra.OnInitialize(initConfig)

	// 配置文件
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
	// 作者信息
	rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
	// 許可證信息
	rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
	// 使用Viper進(jìn)行配置
	rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
	// 將命令行標(biāo)志綁定到 Viper 配置庫(kù)中的相應(yīng)參數(shù)
	err := viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
	if err != nil {
		return
	}
	err2 := viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
	if err2 != nil {
		return
	}
	// 設(shè)置默認(rèn)配置值
	viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
	viper.SetDefault("license", "apache")

	// 用于添加子命令
	rootCmd.AddCommand(addCmd)
	rootCmd.AddCommand(initCmd)
}

// 初始化應(yīng)用程序的配置
func initConfig() {
	// 判斷是否指定了配置文件路徑,如果指定了,則將其設(shè)置為 Viper 配置文件
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	} else {
		// 如果沒(méi)有指定配置文件路徑,就根據(jù)用戶的主目錄動(dòng)態(tài)生成配置文件路徑
		home, err := os.UserHomeDir()
		cobra.CheckErr(err)
		viper.AddConfigPath(home)
		viper.SetConfigType("yaml")
		viper.SetConfigName(".cobra")
	}

	// 用于自動(dòng)讀取環(huán)境變量
	viper.AutomaticEnv()

	// 用于讀取配置文件。如果成功讀取,則輸出使用的配置文件路徑
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}

創(chuàng)建你的 main.go

main.go 文件通常非常裸露。它有一個(gè)目的:初始化 Cobra:

package go_test

import "go-test/cmd"

func main() {
	err := cmd.Execute()
	if err != nil {
		return
	}
}

創(chuàng)建其他命令

可以定義其他命令,并且通常每個(gè)命令都有自己的文件 在 cmd/ 目錄中。

例如:如果要?jiǎng)?chuàng)建版本命令,則需要?jiǎng)?chuàng)建 cmd/version.go 和 使用以下內(nèi)容填充它:

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// 將 versionCmd 命令添加到根命令 rootCmd 中
func init() {
	rootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of Hugo",
	Long:  `All software has versions. This is Hugo's`,
	// 用于定義命令被執(zhí)行時(shí)的具體操作
	// 在本例中,當(dāng)執(zhí)行 version 命令時(shí),會(huì)打印出 “Hugo Static Site Generator v0.9 – HEAD” 版本信息
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
	},
}

結(jié)合上面的代碼,當(dāng)用戶輸入 cobra-cli version 時(shí),將會(huì)觸發(fā) versionCmd 命令的執(zhí)行,打印出應(yīng)用程序的版本信息

子命令

命令可能具有子命令,而子命令又可能具有其他子命令

請(qǐng)考慮以下目錄結(jié)構(gòu):AddCommand

├── cmd
│   ├── root.go
│   └── sub1
│       ├── sub1.go
│       └── sub2
│           ├── leafA.go
│           ├── leafB.go
│           └── sub2.go
└── main.go

返回和處理錯(cuò)誤

如果您希望向命令的調(diào)用方返回錯(cuò)誤,可以使用RunE

package cmd

import (
  "fmt"

  "github.com/spf13/cobra"
)

func init() {
  rootCmd.AddCommand(tryCmd)
}

var tryCmd = &cobra.Command{
  Use:   "try",
  Short: "Try and possibly fail at something",
  RunE: func(cmd *cobra.Command, args []string) error {
    if err := someFunc(); err != nil {
	return err
    }
    return nil
  },
}

3.cobra使用標(biāo)志

標(biāo)志提供修飾符來(lái)控制操作命令的運(yùn)行方式

1、持久性標(biāo)志

標(biāo)志可以是“持久性的”,這意味著此標(biāo)志將可用于它所分配的命令以及該命令下的每個(gè)命令。為全局標(biāo)志,將標(biāo)志指定為根上的持久標(biāo)志

持久性標(biāo)記的定義通常包括全局性的配置參數(shù),例如日志級(jí)別、配置文件路徑、全局選項(xiàng)等

rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

2、本地標(biāo)志

在本地分配標(biāo)志,該標(biāo)志僅適用于該特定命令

本地標(biāo)記通常用于定義特定命令所需的選項(xiàng)和參數(shù),例如某個(gè)命令的特定配置選項(xiàng)

localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")

3、使用 Config 綁定標(biāo)志

可以使用 viper 綁定您的標(biāo)志:

var author string

func init() {
  rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}

使用 Viper 綁定命令行標(biāo)志可使配置管理更加一致、靈活和可組合。然而,具體是否需要綁定命令行標(biāo)志取決于你的應(yīng)用程序需求和偏好,如果你認(rèn)為手動(dòng)處理命令行標(biāo)志更適合你,也可以不使用 Viper 進(jìn)行綁定

4、參數(shù)必須

默認(rèn)情況下,標(biāo)志是可選的,如果想設(shè)置某個(gè)參數(shù)是必要的,可以進(jìn)行設(shè)置:

rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region")

或者,對(duì)于持久性標(biāo)志:

rootCmd.PersistentFlags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkPersistentFlagRequired("region")

5、標(biāo)記Groups

如果您有不同的標(biāo)志必須一起提供(例如,如果他們提供標(biāo)志,他們也必須提供標(biāo)志),也可以強(qiáng)制進(jìn)行設(shè)定:

rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
rootCmd.MarkFlagsRequiredTogether("username", "password")

還可以設(shè)置不同標(biāo)記的互斥(也就是不能同時(shí)出現(xiàn)):

rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")

如果要要求組中至少有一個(gè)標(biāo)志存在,也可以指定:

rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
rootCmd.MarkFlagsOneRequired("json", "yaml")
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")

4.Cobra位置參數(shù)和自定義參數(shù)

可以指定位置參數(shù)的驗(yàn)證:

內(nèi)置了以下驗(yàn)證器:Args Command

參數(shù)數(shù)量:

  • NoArgs- 如果有任何位置參數(shù),則報(bào)告錯(cuò)誤。
  • ArbitraryArgs- 接受任意數(shù)量的參數(shù)。
  • MinimumNArgs(int)- 如果提供的位置參數(shù)少于 N 個(gè),則報(bào)告錯(cuò)誤。
  • MaximumNArgs(int)- 如果提供了超過(guò) N 個(gè)位置參數(shù),則報(bào)告錯(cuò)誤。
  • ExactArgs(int)- 如果位置參數(shù)不完全是 N 個(gè),則報(bào)告錯(cuò)誤。
  • RangeArgs(min, max)- 如果參數(shù)數(shù)不在min和max之間,則報(bào)告錯(cuò)誤

論據(jù)內(nèi)容:

  • OnlyValidArgs- 如果字段中未指定任何位置參數(shù),則報(bào)告錯(cuò)誤

此外,還可以將現(xiàn)有檢查與任意其他檢查相結(jié)合,例如:

var cmd = &cobra.Command{
  Short: "hello",
  Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hello, World!")
  },
}

可以設(shè)置任何滿足的自定義驗(yàn)證器,例如:

var cmd = &cobra.Command{
  Short: "hello",
  Args: func(cmd *cobra.Command, args []string) error {
    if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {
        return err
    }
    // 運(yùn)行自定義驗(yàn)證邏輯
    if myapp.IsValidColor(args[0]) {
      return nil
    }
    return fmt.Errorf("invalid color specified: %s", args[0])
  },
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hello, World!")
  },
}

5.Cobra PreRun和PostRun鉤子

在 Cobra 庫(kù)中,命令的執(zhí)行過(guò)程被分為多個(gè)階段,并且 Cobra 提供了一些Hooks來(lái)允許開(kāi)發(fā)者在這些階段插入自定義的行為

1、PersistentPreRun

在執(zhí)行任何命令之前調(diào)用 PersistentPreRun。可以使用這個(gè)鉤子來(lái)進(jìn)行全局的初始化操作或者檢查全局的配置參數(shù)

2、PreRun

在執(zhí)行該命令之前調(diào)用 PreRun。可以使用這個(gè)鉤子來(lái)執(zhí)行一些與特定命令相關(guān)的操作或配置檢查

3、Run

當(dāng)命令被執(zhí)行時(shí),會(huì)調(diào)用 Run 函數(shù)來(lái)執(zhí)行實(shí)際的命令操作

4、PostRun

在執(zhí)行完該命令之后調(diào)用 PostRun。可以使用這個(gè)鉤子來(lái)執(zhí)行一些與特定命令相關(guān)的清理工作或后處理操作

5、PersistentPostRun

在執(zhí)行完任何命令之后調(diào)用 PersistentPostRun??梢允褂眠@個(gè)鉤子來(lái)進(jìn)行全局的清理工作或輸出全局概要信息

例如:

package main

import (
  "fmt"

  "github.com/spf13/cobra"
)

func main() {

  var rootCmd = &cobra.Command{
    Use:   "root [sub]",
    Short: "My root command",
    PersistentPreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
    },
    PreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
    },
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd Run with args: %v\n", args)
    },
    PostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
    },
    PersistentPostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
    },
  }

  var subCmd = &cobra.Command{
    Use:   "sub [no options!]",
    Short: "My subcommand",
    PreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
    },
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd Run with args: %v\n", args)
    },
    PostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
    },
    PersistentPostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
    },
  }

  rootCmd.AddCommand(subCmd)

  rootCmd.SetArgs([]string{""})
  rootCmd.Execute()
  fmt.Println()
  rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
  rootCmd.Execute()
}

輸出:

Inside rootCmd PersistentPreRun with args: []
Inside rootCmd PreRun with args: []
Inside rootCmd Run with args: []
Inside rootCmd PostRun with args: []
Inside rootCmd PersistentPostRun with args: []

Inside rootCmd PersistentPreRun with args: [arg1 arg2]
Inside subCmd PreRun with args: [arg1 arg2]
Inside subCmd Run with args: [arg1 arg2]
Inside subCmd PostRun with args: [arg1 arg2]
Inside subCmd PersistentPostRun with args: [arg1 arg2]

到此這篇關(guān)于Go語(yǔ)言命令行參數(shù)及cobra使用方法的文章就介紹到這了,更多相關(guān)Go語(yǔ)言命令行參數(shù)及cobra內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你理解Go語(yǔ)言中方法的本質(zhì)

    一文帶你理解Go語(yǔ)言中方法的本質(zhì)

    我們知道,Go語(yǔ)言從設(shè)計(jì)伊始,就不支持經(jīng)典的面向?qū)ο笳Z(yǔ)法元素,但?Go?語(yǔ)言仍保留了名為“方法(method)”的語(yǔ)法元素,下面我們就來(lái)帶大家深入了解一下Go語(yǔ)言中的方法吧
    2023-11-11
  • go內(nèi)存緩存BigCache之Entry封裝源碼閱讀

    go內(nèi)存緩存BigCache之Entry封裝源碼閱讀

    這篇文章主要介紹了go內(nèi)存緩存BigCache之Entry封裝源碼閱讀
    2023-09-09
  • golang編程開(kāi)發(fā)使用sort排序示例詳解

    golang編程開(kāi)發(fā)使用sort排序示例詳解

    這篇文章主要為大家介紹了go語(yǔ)言編程開(kāi)發(fā)使用sort來(lái)排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • Go接口的用法詳解

    Go接口的用法詳解

    本文主要介紹了Go接口的用法詳解,包括定義接口、實(shí)現(xiàn)接口、使用接口、空接口等,通過(guò)接口,可以實(shí)現(xiàn)多態(tài)性,即一個(gè)對(duì)象可以實(shí)現(xiàn)多個(gè)接口,從而實(shí)現(xiàn)不同接口的行為,感興趣的可以了解一下
    2023-11-11
  • golang讀取yaml配置文件的方法實(shí)現(xiàn)

    golang讀取yaml配置文件的方法實(shí)現(xiàn)

    本文主要介紹了golang讀取yaml配置文件的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Go語(yǔ)言中常量定義方法實(shí)例分析

    Go語(yǔ)言中常量定義方法實(shí)例分析

    這篇文章主要介紹了Go語(yǔ)言中常量定義方法,以實(shí)例形式分析了Go語(yǔ)言中常量的定義及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go 1.18新特性之泛型的全面講解

    Go 1.18新特性之泛型的全面講解

    本文力求能讓未接觸過(guò)泛型編程的人也能較好理解Go的泛型,所以行文可能略顯啰嗦。但是請(qǐng)相信我,看完這篇文章你能獲得對(duì)Go泛型非常全面的了解
    2023-03-03
  • 使用gorm.Scopes函數(shù)實(shí)現(xiàn)復(fù)用查詢邏輯示例

    使用gorm.Scopes函數(shù)實(shí)現(xiàn)復(fù)用查詢邏輯示例

    這篇文章主要為大家介紹了使用gorm.Scopes函數(shù)實(shí)現(xiàn)復(fù)用查詢邏輯示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    在軟件開(kāi)發(fā)的世界里,數(shù)據(jù)類型轉(zhuǎn)換是一項(xiàng)基礎(chǔ)而重要的技能,尤其在Go語(yǔ)言這樣類型嚴(yán)格的語(yǔ)言中,正確高效地進(jìn)行類型轉(zhuǎn)換對(duì)于性能優(yōu)化和代碼質(zhì)量至關(guān)重要,本文給大家介紹了Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換,需要的朋友可以參考下
    2024-02-02
  • Golang如何讀取單行超長(zhǎng)的文本詳解

    Golang如何讀取單行超長(zhǎng)的文本詳解

    這篇文章主要給大家介紹了關(guān)于Golang如何讀取單行超長(zhǎng)文本的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-12-12

最新評(píng)論