任何進(jìn)程啟動(dòng)時(shí)都可以賦予一個(gè)字符串?dāng)?shù)組作為參數(shù),一般名為ARGV或ARGS。
通過(guò)解析這些參數(shù)可以讓你的程序更加通用,例如cp命令通過(guò)給定兩個(gè)參數(shù)就可以復(fù)制任意的文件,當(dāng)然如果需要的參數(shù)太多最好還是使用配置文件。
進(jìn)程參數(shù)一般可分為兩類,一是Argument,也就是作為進(jìn)程運(yùn)行的實(shí)體參數(shù)。例如cp config.yml config.yml.bak的這兩個(gè)參數(shù)。
設(shè)計(jì)Go程序時(shí)可以輕易地獲得這些參數(shù),argument.go代碼如下,代碼來(lái)自https://gobyexample.com/command-line-arguments。
package main
import "os"
import "fmt"
func main() {
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
arg := os.Args[3]
fmt.Println(argsWithProg)
fmt.Println(argsWithoutProg)
fmt.Println(arg)
}
運(yùn)行效果如下。
$ go build command-line-arguments.go
$ ./command-line-arguments a b c d
[./command-line-arguments a b c d]
[a b c d]
c
可以看出通過(guò)os.Args,不管是不是實(shí)體參數(shù)都可以獲得,但是對(duì)于類似開(kāi)關(guān)的輔助參數(shù),Go提供了另一種更好的方法。
使用Flag可以更容易得將命令行參數(shù)轉(zhuǎn)化成我們需要的數(shù)據(jù)類型,其中flag.go代碼如下,代碼來(lái)自https://gobyexample.com/command-line-flags。
package main
import "flag"
import "fmt"
func main() {
wordPtr := flag.String("word", "foo", "a string")
numbPtr := flag.Int("numb", 42, "an int")
boolPtr := flag.Bool("fork", false, "a bool")
var svar string
flag.StringVar(&svar, "svar", "bar", "a string var")
flag.Parse()
fmt.Println("word:", *wordPtr)
fmt.Println("numb:", *numbPtr)
fmt.Println("fork:", *boolPtr)
fmt.Println("svar:", svar)
fmt.Println("tail:", flag.Args())
}
運(yùn)行結(jié)果如下,相比直接使用os.Args代碼也簡(jiǎn)潔了不少。
root@87096bf68cb2:/go/src# ./flag -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
fork: true
svar: flag
tail: []
root@87096bf68cb2:/go/src# ./flag -h
Usage of ./flag:
-fork=false: a bool
-numb=42: an int
-svar="bar": a string var
-word="foo": a string
使用Go獲取進(jìn)程參數(shù)是很簡(jiǎn)單的,不過(guò)一旦參數(shù)太多,最佳實(shí)踐還是使用配置文件。
進(jìn)程參數(shù)只有在啟動(dòng)進(jìn)程時(shí)才能賦值,如果需要在程序運(yùn)行時(shí)進(jìn)行交互,就需要了解進(jìn)程的輸入與輸出了。