进程参数

任何进程启动时都可以赋予一个字符串数组作为参数,一般名为ARGV或ARGS。

通过解析这些参数可以让你的程序更加通用,例如cp命令通过给定两个参数就可以复制任意的文件,当然如果需要的参数太多最好还是使用配置文件。

获得进程Argument

进程参数一般可分为两类,一是Argument,也就是作为进程运行的实体参数。例如cp config.yml config.yml.bak的这两个参数。

设计Go程序时可以轻易地获得这些参数,argument.go代码如下,代码来自https://gobyexample.com/command-line-arguments

  1. package main
  2. import "os"
  3. import "fmt"
  4. func main() {
  5. argsWithProg := os.Args
  6. argsWithoutProg := os.Args[1:]
  7. arg := os.Args[3]
  8. fmt.Println(argsWithProg)
  9. fmt.Println(argsWithoutProg)
  10. fmt.Println(arg)
  11. }

运行效果如下。

  1. $ go build command-line-arguments.go
  2. $ ./command-line-arguments a b c d
  3. [./command-line-arguments a b c d]
  4. [a b c d]
  5. c

可以看出通过os.Args,不管是不是实体参数都可以获得,但是对于类似开关的辅助参数,Go提供了另一种更好的方法。

获得进程Flag

使用Flag可以更容易得将命令行参数转化成我们需要的数据类型,其中flag.go代码如下,代码来自https://gobyexample.com/command-line-flags

  1. package main
  2. import "flag"
  3. import "fmt"
  4. func main() {
  5. wordPtr := flag.String("word", "foo", "a string")
  6. numbPtr := flag.Int("numb", 42, "an int")
  7. boolPtr := flag.Bool("fork", false, "a bool")
  8. var svar string
  9. flag.StringVar(&svar, "svar", "bar", "a string var")
  10. flag.Parse()
  11. fmt.Println("word:", *wordPtr)
  12. fmt.Println("numb:", *numbPtr)
  13. fmt.Println("fork:", *boolPtr)
  14. fmt.Println("svar:", svar)
  15. fmt.Println("tail:", flag.Args())
  16. }

运行结果如下,相比直接使用os.Args代码也简洁了不少。

  1. root@87096bf68cb2:/go/src# ./flag -word=opt -numb=7 -fork -svar=flag
  2. word: opt
  3. numb: 7
  4. fork: true
  5. svar: flag
  6. tail: []
  7. root@87096bf68cb2:/go/src# ./flag -h
  8. Usage of ./flag:
  9. -fork=false: a bool
  10. -numb=42: an int
  11. -svar="bar": a string var
  12. -word="foo": a string

使用Go获取进程参数是很简单的,不过一旦参数太多,最佳实践还是使用配置文件。

进程参数只有在启动进程时才能赋值,如果需要在程序运行时进行交互,就需要了解进程的输入与输出了。