Go命令行參數(shù)解析flag 包使用示例詳解
Go]命令行參數(shù)解析包(flag 包)使用詳解
Go 的 flag 包可以解析命令行的參數(shù)。
一、命令行語(yǔ)法
命令行語(yǔ)法主要有以下幾種形式:
cmd -flag // 只支持bool類型
cmd -flag=xxx
cmd -flag xxx // 只支持非bool類型
以上語(yǔ)法對(duì)于一個(gè)或兩個(gè)‘-’號(hào)是一樣的,即
cmd -flag xxx (使用空格,一個(gè) - 符號(hào))
cmd --flag xxx (使用空格,兩個(gè) - 符號(hào))
cmd -flag=xxx (使用等號(hào),一個(gè) - 符號(hào))
cmd --flag=xxx (使用等號(hào),兩個(gè) - 符號(hào))
對(duì)于整形 flag,合法的值可以為 1234,0664,0x1234 或 負(fù)數(shù) 等。對(duì)于布爾型 flag,可以為 1,0,t,f,T,F(xiàn),true,false,TRUE,F(xiàn)ALSE,True,F(xiàn)alse 等
其中,布爾類型的參數(shù)比較特殊,為了防止解析時(shí)的二義性,應(yīng)該使用 等號(hào) 的方式指定
二、命令行參數(shù)方法
1.定義flag參數(shù)
參數(shù)有三個(gè):第一個(gè)為 參數(shù)名稱,第二個(gè)為 默認(rèn)值,第三個(gè)是 使用說(shuō)明
1>通過(guò) flag.String(),Bool(),Int() 等 flag.Xxx() 方法,該種方式返回一個(gè)相應(yīng)的指針
var ip = flag.Int("flagname", 1234, "help message for flagname")
2>通過(guò) flag.XxxVar() 方法將 flag 綁定到一個(gè)變量,該種方式返回 值類型,如
var flagvar intflag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
3> 通過(guò) flag.Var() 綁定自定義類型,自定義類型需要實(shí)現(xiàn) Value 接口 (Receiver 必須為指針),如
flag.Var(&flagVal, "name", "help message for flagname")
2. 調(diào)用 flag.Parse() 解析命令行參數(shù)到定義的 flag
flag.Parse()
解析函數(shù)將會(huì)在碰到第一個(gè) 非flag 命令行參數(shù)時(shí)停止,非flag 命令行參數(shù)是指不滿足命令行語(yǔ)法的參數(shù),如命令行參數(shù)為 cmd --flag=true abc 則第一個(gè) 非flag 命令行參數(shù)為“abc”
3. 調(diào)用 Parse 解析后,就可以直接使用 flag 本身(指針類型)或者綁定的變量了(值類型)
fmt.Println("flagvar has value ", flagvar)
還可通過(guò) flag.Args(), flag.Arg(i) 來(lái)獲取 非flag 命令行參數(shù)!
三、實(shí)例
package main import ( "flag" "fmt" ) func main() { username := flag.String("name", "", "Input your username") flag.Parse() fmt.Println("Hello, ", *username) }
編譯:
go build flag.go
運(yùn)行:
./flag -name=world
輸出:
Hello, world
Go 還允許 自定義“命令行參數(shù)解析規(guī)則”,如下接口所示:
FlagSet 結(jié)構(gòu):
type FlagSet struct { Usage func() }
示例:
package main import ( "flag" "fmt" ) var myFlagSet = flag.NewFlagSet("myflagset", flag.ExitOnError) var stringFlag = myFlagSet.String("abc", "default value", "help mesage") func main() { myFlagSet.Parse([]string{"-abc", "def", "ghi", "123"}) args := myFlagSet.Args() for i := range args { fmt.Println(i, myFlagSet.Arg(i)) } }
Go-命令行參數(shù)解析
1. 解析命令行參數(shù)
程序在執(zhí)行時(shí),獲取在命令行啟動(dòng)程序是使用的參數(shù)
- 命令行( Command line interface -- CLI):基于文本來(lái)查看、處理、操作計(jì)算機(jī)的界面,又被稱為 終端、控制臺(tái)
- 命令:在命令行執(zhí)行的程序,一般是一行,包含命令名字、子命令與命令相關(guān)的選項(xiàng)(Flag),
- Flag:傳遞給命令的參數(shù),通過(guò)參數(shù)全稱或者參數(shù)首字符指定參數(shù)名稱,參數(shù)之后使用
=
或空格連接參數(shù)與參數(shù)值
2. Golang 獲取命令行參數(shù)
os.Args: 返回一個(gè)字符串slice,第一個(gè)當(dāng)前程序自身路徑,剩余參數(shù)是傳遞給命令行的參數(shù)
傳遞的參數(shù)一般是
--key=value
形式 、簡(jiǎn)寫-k value
形式或者是一個(gè)開關(guān)標(biāo)志-k
,使用os.Args
只是獲取一個(gè)以空格分隔的字符串列表,無(wú)法很好的解析傳遞進(jìn)來(lái)的參數(shù)到變量中
package main import ( "fmt" "os" ) func main() { commandArgs := os.Args fmt.Println(commandArgs) }
# 執(zhí)行程序: 遞歸瀏覽指定目錄下所有文件 go run main.go --name ls --value /etc -r # 輸出: [/tmp/go-build2637413899/b001/exe/main --name ls --value /etc -r]
- 命令行參數(shù)解析 -- flag包
需要知曉程序的命令行需要傳遞哪些參數(shù),如果沒(méi)有傳遞該參數(shù),那么默認(rèn)值是什么,參數(shù)的說(shuō)明
使用flag的流程: 1. 初始化存放命令行參數(shù)的全局變量 2. 在main包的init函數(shù)中注冊(cè)需要解析的命令行參數(shù),包含參數(shù)的類型、參數(shù)存放到哪個(gè)變量、參數(shù)的名稱、參數(shù)的默認(rèn)值、參數(shù)的使用說(shuō)明 3. 在定義解析命令行參數(shù)最后,添加 flag.Parse(),解析傳遞到程序的命令行參數(shù)到變量中 4. 主函數(shù)中通過(guò)全局變量引用命令行參 5. 運(yùn)行主函數(shù),通過(guò) -<參數(shù)名>=<value> 或 -<參數(shù)名> <value> 方式傳參 解析命令行參數(shù)的基本文法: 1. flag.<類型>Var(<指針>, <參數(shù)名稱>, <默認(rèn)值>, <用法說(shuō)明>) 2. 等價(jià)方法: flag.<類型>(<參數(shù)名稱>, <默認(rèn)值>, <用法說(shuō)明>) - 區(qū)別在于,Var后綴方法是通過(guò)指針將值存放到指針指向的變量,未帶Var后綴的方法返回一個(gè)指定值的指針 - 相同的,參數(shù)值不同則使用不同的類型,都包含參數(shù)的名稱、參數(shù)的默認(rèn)值、該參數(shù)使用說(shuō)明 - 類型是基本數(shù)據(jù)類型:int int64 uint uint64 string bool fl0at64 Duration
package main import ( "flag" "fmt" ) // 1. 聲明保存命令行參數(shù)的變量 var ( name string value string isRecursive bool ) func init() { // 2. 注冊(cè)需要解析的命令行參: 參數(shù)名、默認(rèn)值、參數(shù)說(shuō)明 flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱") flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)") flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸") // 3. 解析命令行參數(shù) flag.Parse() } func main() { // 4. 主程序中通過(guò)全局變量引用命令行參 fmt.Println(name, value, isRecursive) }
# 輸出:ls /etc true go run main.go -name ls -value /etc -recursive # 輸出: ls /etc false go run main.go -name ls -value /etc
Flag包相關(guān)的其他方法
flag.Set()
解析后修改或設(shè)置命令行參數(shù)
package main import ( "flag" "fmt" ) // 1. 聲明保存命令行參數(shù)的變量 var ( name string ) func init() { // 2. 聲明需要解析的命令行參: 參數(shù)名、默認(rèn)值、參數(shù)說(shuō)明 flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱") // 將name的值修改為 find flag.Set("name", "find") } func main() { // 4. 主程序中通過(guò)全局變量引用命令行參 fmt.Println(name) }
# 輸出:find go run main.go -name ls
flog.NFlag()
返回被設(shè)置的flag數(shù)量
package main import ( "flag" "fmt" ) // 1. 聲明保存命令行參數(shù)的變量 var ( name string value string isRecursive bool ) func init() { flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱") flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)") flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸") flag.Parse() } func main() { fmt.Println("number of set flag:", flag.NFlag()) }
# 輸出:number of set flag: 2
go run main.go -name ls -value /etc
flag,Parsed()
檢查flag.Parse()
是否被調(diào)用過(guò)
package main import ( "flag" "fmt" ) // 1. 聲明保存命令行參數(shù)的變量 var ( name string value string isRecursive bool ) func init() { flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱") flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)") flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸") flag.Parse() } func main() { fmt.Println("is Parsed", flag.Parsed()) }
# 輸出:is Parsed true
go run main.go -name ls -value /etc
flag.Visit(func (*Flag))
按字典順序遍歷,進(jìn)行設(shè)置了的標(biāo)簽
package main import ( "flag" "fmt" ) // 1. 聲明保存命令行參數(shù)的變量 var ( name string value string isRecursive bool ) func init() { flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱") flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)") flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸") flag.Parse() } func main() { flag.Visit(func(f *flag.Flag) { fmt.Printf("Name: %s, Value: %s, DefValue: %s, Usage: %s \n", f.Name, f.Value, f.DefValue, f.Usage) }) }
# 輸出:
# Name: name, Value: ls, DefValue: none, Usage: 執(zhí)行命令的名稱
# Name: value, Value: /etc, DefValue: none, Usage: 執(zhí)行命令的參數(shù)
go run main.go -name ls -value /etc
到此這篇關(guān)于Go-命令行參數(shù)解析的文章就介紹到這了,更多相關(guān)Go命令行參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang?run時(shí)報(bào)undefined錯(cuò)誤的解決
這篇文章主要介紹了golang?run時(shí)報(bào)undefined錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03詳解go程序如何在windows服務(wù)中開啟和關(guān)閉
這篇文章主要介紹了一個(gè)go程序,如何在windows服務(wù)中優(yōu)雅開啟和關(guān)閉,文中通過(guò)代碼示例和圖文講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-07-07關(guān)于Golang獲取當(dāng)前項(xiàng)目絕對(duì)路徑的問(wèn)題
這篇文章主要介紹了Golang獲取當(dāng)前項(xiàng)目絕對(duì)路徑的問(wèn)題,通常的做法是go run用于本地開發(fā),用一個(gè)命令中快速測(cè)試代碼確實(shí)非常方便;在部署生產(chǎn)環(huán)境時(shí),我們會(huì)通過(guò)go build構(gòu)建出二進(jìn)制文件然后上傳到服務(wù)器再去執(zhí)行,那么會(huì)產(chǎn)生什么問(wèn)題呢?感興趣的朋友一起看看吧2022-04-04詳解Golang實(shí)現(xiàn)http重定向https的方式
這篇文章主要介紹了詳解Golang實(shí)現(xiàn)http重定向https的方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08使用Go語(yǔ)言開發(fā)一個(gè)命令行文件管理工具
這篇文章主要為大家詳細(xì)介紹了如何使用Go語(yǔ)言開發(fā)一款命令行文件管理工具,支持批量重命名,刪除,創(chuàng)建,移動(dòng)文件,需要的小伙伴可以了解下2025-02-02使用Go語(yǔ)言創(chuàng)建WebSocket服務(wù)的實(shí)現(xiàn)示例
這篇文章主要介紹了使用Go語(yǔ)言創(chuàng)建WebSocket服務(wù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Go微服務(wù)網(wǎng)關(guān)的實(shí)現(xiàn)
本文主要介紹了Go微服務(wù)網(wǎng)關(guān)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Go 自動(dòng)升級(jí)依賴版本的幾種方法實(shí)現(xiàn)
Go語(yǔ)言使用GoModules進(jìn)行依賴管理,可以通過(guò)多種方式自動(dòng)升級(jí)依賴,本文就來(lái)介紹Go 自動(dòng)升級(jí)依賴版本的7種方法,感興趣的可以了解一下2025-03-03