我们随便写一个日常使用的psql的命令行用法
view sourceprint?
1. manu@manu-hacks:~$ pg_ctl -D /home/manu/DB_data/ -l /home/manu/DB_data/postgres_manu. log start
2. server starting
这种情况下我们更需要的是解析各个参数的意义,比如-D选项 是通知pg_ctl pgdata的路径在那,-l选项告知的是log记录到那个文件,start相当于子命令,告知action。对于这种命令,我们都知道C语言有getopt及其getopt_long来解决。go语言怎么解决? go语言提供了flag这个package。来应对这种入参的解析。 flag支持的语言格式如下:
-flag // bool类型only -flag=x -flag x //not bool 类型 很自然,这个flag能够解析 -D /home/manu/DB_data,对应第二种类型,我们知道pg_ctl有-W选项,属于一个开关性质的bool型的选项
view sourceprint?
1. -W do not wait until operation completes
自然对应第一种类型,也可以解析。第二种也很好理解。 下面我给出一个例子,简单的解析这个pg_ctl的命令:
view sourceprint?
01. manu@manu-hacks:~/code/go/self$ cat pg_ctl_parse.go
02.
03.
04. package main
05. import (
06. "fmt"
07. "flag"
08. )
09.
10. func main(){
11.
12. data_path := flag.String( "D" , "/home/manu/sample/" , "DB data path" )
13. log_file := flag.String( "l" , "/home/manu/sample.log" , "log file" )
14. nowait_flag :=flag.Bool( "W" , false , "do not wait until operation completes" )
15.
16. flag.Parse()
17.
18. var cmd string = flag.Arg(0);
19.
20. fmt.Printf( "action : %sn" ,cmd)
21. fmt.Printf( "data path: %sn" ,*data_path)
22. fmt.Printf( "log file : %sn" ,*log_file)
23. fmt.Printf( "nowait : %vn" ,*nowait_flag)
24.
25. fmt.Printf( "-------------------------------------------------------n" )
26.
27. fmt.Printf( "there are %d non-flag input paramn" ,flag.NArg())
28. for i,param := range flag.Args(){
29. fmt.Printf( "#%d :%sn" ,i,param)
30. }
31.
32.
33. }
OK,我们分析下代码(分割线下面的我们暂时不看): 第一行对应的是data_path的解析规则 -D选项对应的值是字符串类型字符串, 默认值是“/home/manu/sample”, DB data path提示信息或者help信息或者说明是。
view sourceprint?
01. manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go -D /home/manu/DB_data/ -l /home/manu/DB_data/postgres_manu.log -W start
02. action : start
03. data path: /home/manu/DB_data/
04. log file : /home/manu/DB_data/postgres_manu.log
05. nowait : true
06. -------------------------------------------------------
07. there are 1 non-flag input param
08. #0 :start
09.
10. manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go -l=/home/manu/DB_data/postgres_manu.log -W -D /home/manu/DB_data/ start
11. action : start
12. data path: /home/manu/DB_data/
13. log file : /home/manu/DB_data/postgres_manu.log
14. nowait : true
15. -------------------------------------------------------
16. there are 1 non-flag input param
17. #0 :start
我们看到了,解析出了data_path,log_file无论 -l -D出现的顺序如何,只要正常的出现了,就能正常的解析。 但是晴朗的天空中也有一片乌云,start不是这种 -key=alue 或则-option的类型,flag是解析不了的。我们称这种参数为non-flag参数,flag解析遇到non-flag参数就停止了:
view sourceprint?
1. s := f.args[0]
2. if len(s) == 0 || s[0] != '-' || len(s) == 1 {
3. return false ,nil
4. }
所以如果我们将non-flag参数放在最前面,flag什么也不会解析,因为flag遇到了这个就停止解析了。
view sourceprint?
01. manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go start -l=/home/manu/DB_data/postgres_manu.log -W -D /home/manu/DB_data/
02. action : start
03. data path: /home/manu/sample
04. log file : /home/manu/sample.log
05. nowait : false
06. -------------------------------------------------------
07. there are 5 non-flag input param
08. #0 :start
09. #1 :-l=/home/manu/DB_data/postgres_manu.log
10. #2 :-W
11. #3 :-D
12. #4 :/home/manu/DB_data/
OK,flag提供了Arg(i),Args()来获取non-flag参数,NArg()来获取non-flag的个数。正如我们们sample 代码看到的。
view sourceprint?
1. fmt.Printf( "there are %d non-flag input paramn" ,flag.NArg())
2. for i,param := range flag.Args(){
3. fmt.Printf( "#%d :%sn" ,param)
4. }
flag还提供了NFlag()获取那些匹配上的参数的个数。 从例子上看,flag package很有用,但是并没有强大到解析一切的程度。 如果你有类似-option或者-key =value这种参数,不妨试试 flag。如果你的入参解析非常复杂,flag可能捉襟见肘。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|