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 标准库—命令行参数解析flag
2 Go 语言简介(下)— 特性
有疑问加站长微信联系(非本文作者)