Golang實(shí)現(xiàn)獲取與解析命令行參數(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è)開(kāi)關(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)于Golang實(shí)現(xiàn)獲取與解析命令行參數(shù)的文章就介紹到這了,更多相關(guān)Go命令行參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Go基于WebSocket構(gòu)建千萬(wàn)級(jí)視頻直播彈幕系統(tǒng)的代碼詳解
這篇文章主要介紹了使用Go基于WebSocket構(gòu)建千萬(wàn)級(jí)視頻直播彈幕系統(tǒng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
利用systemd部署golang項(xiàng)目的實(shí)現(xiàn)方法
這篇文章主要介紹了利用systemd部署golang項(xiàng)目的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
go-zero熔斷機(jī)制組件Breaker接口定義使用解析
這篇文章主要為大家介紹了go-zero熔斷機(jī)制組件Breaker接口定義使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
golang與非golang程序探測(cè)beyla源碼解讀
這篇文章主要為大家介紹了beyla源碼解讀之golang與非golang程序的探測(cè)實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Go語(yǔ)言網(wǎng)絡(luò)故障診斷與調(diào)試技巧
在分布式系統(tǒng)和微服務(wù)架構(gòu)的浪潮中,網(wǎng)絡(luò)編程成為系統(tǒng)性能和可靠性的核心支柱,從高并發(fā)的API服務(wù)到實(shí)時(shí)通信應(yīng)用,網(wǎng)絡(luò)的穩(wěn)定性直接影響用戶體驗(yàn),本文面向熟悉Go基本語(yǔ)法和網(wǎng)絡(luò)編程概念,通過(guò)實(shí)際項(xiàng)目經(jīng)驗(yàn)、可運(yùn)行的代碼示例和踩坑教訓(xùn),為你提供一套系統(tǒng)化的網(wǎng)絡(luò)診斷方法2025-08-08
Go anko實(shí)現(xiàn)支持腳本語(yǔ)言
anko是一個(gè)可以讓 Go 項(xiàng)目支持腳本語(yǔ)言的小工具,換句話說(shuō),就是可以給 Go 項(xiàng)目加點(diǎn)“腳本魔法”,下面就跟隨小編一起來(lái)學(xué)習(xí)一下他的具體使用吧2024-11-11
一文深入探索Go語(yǔ)言中的循環(huán)結(jié)構(gòu)
在編程中,循環(huán)結(jié)構(gòu)扮演著重要的角色,它使我們能夠有效地重復(fù)執(zhí)行特定的代碼塊,以實(shí)現(xiàn)各種任務(wù)和邏輯,在Go語(yǔ)言中,for 是 Go 中唯一的循環(huán)結(jié)構(gòu),本文將深入探討Go語(yǔ)言中的for循環(huán)類型以及它們的用法2023-08-08

