http://blog.chinaunix.net/uid-24774106-id-3990722.html
我们写习惯了C代码,都知道了解析输入参数argc argv,获取环境变量env,常见的C语言main函数有:
- int main(int argc,char* argv[],char** envp)
- manu@manu-hacks:~/code/c/self/env$ cat env.c
-
- #include<stdio.h>
- #include<stdlib.h>
-
-
- int main(int argc,char* argv[],char** envp)
- {
- int i;
- printf("there are %d input param\n",argc);
- printf("they are :\n");
- for(i = 0 ; i < argc ; i++)
- {
- printf("%s\n",argv[i]);
- }
-
- printf("env LIST--------------------------------------\n");
- char **p = envp;
- for(;*p != NULL;p++)
- {
- printf("%s\n",*p);
- }
- return 0;
- }
- manu@manu-hacks:~/code/go/self$ godoc os Args
- PACKAGE DOCUMENTATION
-
- package os
- import "os"
-
-
-
- VARIABLES
-
- var Args []string
- Args hold the command-line arguments, starting with the program name.
- manu@manu-hacks:~/code/go/self$ cat sum.go
- package main
- import "fmt"
- import "os"
- import "strconv"
-
-
- func main() int{
- arg_num := len(os.Args)
- fmt.Printf("the num of input is %d\n",arg_num)
-
- fmt.Printf("they are :\n")
- for i := 0 ; i < arg_num ;i++{
- fmt.Println(os.Args[i])
- }
-
- sum := 0
- for i := 1 ; i < arg_num; i++{
- curr,err := strconv.Atoi(os.Args[i])
- if(err != nil){
- fmt.Println("error happened ,exit")
- return 1
- }
- sum += curr
- }
-
- fmt.Printf("sum of Args is %d\n",sum)
- return 0
- }
- manu@manu-hacks:~/code/go/self$ ./sum 1 2 4
- the num of input is 4
- they are :
- ./sum
- 1
- 2
- 4
- sum of Args is 7
- manu@manu-hacks:~/code/go/self$ ./sum 1 2 4 f 5
- the num of input is 6
- they are :
- ./sum
- 1
- 2
- 4
- f
- 5
- error happened ,exit
- FUNCTIONS
-
- func Environ() []string
- Environ returns a copy of strings representing the environment, in the
- form "key=value".
-
- func Getenv(key string) string
- Getenv retrieves the value of the environment variable named by the key.
- It returns the value, which will be empty if the variable is not
- present.
- manu@manu-hacks:~/code/go/self$ cat env.go
- package main
- import "fmt"
- import "os"
-
- func main(){
-
- environ := os.Environ()
- for i := range environ {
- fmt.Println(environ[i])
- }
- fmt.Println("------------------------------------------------------------\n")
- logname := os.Getenv("LOGNAME")
- fmt.Printf("logname is %s\n",logname)
- }
- manu@manu-hacks:~/code/go/self$ go run env.go
- SSH_AGENT_PID=2331
- GPG_AGENT_INFO=/tmp/keyring-5CkALe/gpg:0:1
- TERM=xterm
- SHELL=/bin/bash
- 。。。
-
- ------------------------------------------------------------
-
- logname is manu
1 Package os
我们随便写一个日常使用的psql的命令行用法
- manu@manu-hacks:~$ pg_ctl -D /home/manu/DB_data/ -l /home/manu/DB_data/postgres_manu.log start
- server starting
go语言提供了flag这个package。来应对这种入参的解析。
flag支持的语言格式如下:
- -flag // bool类型only
- -flag=x
- -flag x //not bool 类型
- -W do not wait until operation completes
下面我给出一个例子,简单的解析这个pg_ctl的命令:
- manu@manu-hacks:~/code/go/self$ cat pg_ctl_parse.go
- package main
- import (
- "fmt"
- "flag"
- )
-
- func main(){
-
- data_path := flag.String("D","/home/manu/sample/","DB data path")
- log_file := flag.String("l","/home/manu/sample.log","log file")
- nowait_flag :=flag.Bool("W",false,"do not wait until operation completes")
-
- flag.Parse()
-
- var cmd string = flag.Arg(0);
-
- fmt.Printf("action : %s\n",cmd)
- fmt.Printf("data path: %s\n",*data_path)
- fmt.Printf("log file : %s\n",*log_file)
- fmt.Printf("nowait : %v\n",*nowait_flag)
-
- fmt.Printf("-------------------------------------------------------\n")
-
- fmt.Printf("there are %d non-flag input param\n",flag.NArg())
- for i,param := range flag.Args(){
- fmt.Printf("#%d :%s\n",i,param)
- }
-
-
- }
第一行对应的是data_path的解析规则
-D选项对应的值是字符串类型字符串,
默认值是“/home/manu/sample”,
DB data path提示信息或者help信息或者说明是。
- 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
action : start
data path: /home/manu/DB_data/
log file : /home/manu/DB_data/postgres_manu.log
nowait : true
-------------------------------------------------------
there are 1 non-flag input param
#0 :start
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
action : start
data path: /home/manu/DB_data/
log file : /home/manu/DB_data/postgres_manu.log
nowait : true
-------------------------------------------------------
there are 1 non-flag input param
#0 :start
但是晴朗的天空中也有一片乌云,start不是这种 -key=alue 或则-option的类型,flag是解析不了的。我们称这种参数为non-flag参数,flag解析遇到non-flag参数就停止了:
- s := f.args[0]
- if len(s) == 0 || s[0] != '-' || len(s) == 1 {
- return false, nil
- }
- 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/
action : start
data path: /home/manu/sample
log file : /home/manu/sample.log
nowait : false
-------------------------------------------------------
there are 5 non-flag input param
#0 :start
#1 :-l=/home/manu/DB_data/postgres_manu.log
#2 :-W
#3 :-D
#4 :/home/manu/DB_data/
- fmt.Printf("there are %d non-flag input param\n",flag.NArg())
- for i,param := range flag.Args(){
- fmt.Printf("#%d :%s\n",i,param)
- }
从例子上看,flag package很有用,但是并没有强大到解析一切的程度。
如果你有类似-option或者-key =value这种参数,不妨试试 flag。如果你的入参解析非常复杂,flag可能捉襟见肘。
参考文献:
1
2