http://blog.chinaunix.net/uid-24774106-id-3990722.html
我们写习惯了C代码,都知道了解析输入参数argc argv,获取环境变量env,常见的C语言main函数有:
- intmain(intargc,char*argv[]**envp)
manu@manu-hacks:~/code/c/self/env$ cat env.c
#include<stdio.h>
#include<stdlib>
)
{
inti;
printf"there are %d input param\n")"they are :\n";
for(i=0;i<argc+{
printf"%s\n"[i}
printf"env LIST--------------------------------------\n";
char*p=envp(;!=NULL;p}
return 0}
golang自然也可以做到,获取命令行参数,获取环境变量。
/code/go/self$ godoc os Args
PACKAGE DOCUMENTATION
package os
import"os"
VARIABLES
var Args]string
Args hold the command-line argumentsname.
我们先写一个简单的获取命令行参数的go 程序:
/go/self$ cat sum.go
package main
import"fmt"
import"os"
import"strconv"
func main) int{
arg_num=lenos.Args)
fmt.Printf"the num of input is %d\n")
fmtfori<arg_num{
fmt.Println(os.Args}
sum=0
=1{
currerrstrconvAtoiif=nil"error happened,exit")
return 1
}
sum=curr
}
fmt"sum of Args is %d\n")
return 0
}
输出如下:
/code/go/self$./sum 1 2 4
the numofinput is 4
they are:
/sum
1
2
4
sumofArgs is 7
manu@manu/sum 1 2 4 f 5
the numofinput is 6
they are/sum
1
2
4
f
5
error happened获取环境变量。对于C而言,直接就是之际而言os中也有获取环境变量的函数:
1 Package os
go语言提供了flag这个package。来应对这种入参的解析。
flag支持的语言格式如下:
下面我给出一个例子,简单的解析这个pg_ctl的命令:
第一行对应的是data_path的解析规则
-D选项对应的值是字符串类型字符串,
默认值是“/home/manu/sample”,
DB data path提示信息或者help信息或者说明是。
但是晴朗的天空中也有一片乌云,start不是这种 -key=alue 或则-option的类型,flag是解析不了的。我们称这种参数为non-flag参数,flag解析遇到non-flag参数就停止了:
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/
OK,flag提供了Arg(i),Args()来获取non-flag参数,NArg()来获取non-flag的个数。正如我们们sample 代码看到的。
从例子上看,flag package很有用,但是并没有强大到解析一切的程度。
如果你有类似-option或者-key =value这种参数,不妨试试 flag。如果你的入参解析非常复杂,flag可能捉襟见肘。
参考文献:
1 标准库—命令行参数解析flag
2 Go 语言简介(下)— 特性 原文链接:https://www.f2er.com/go/190024.html
FUNCTIONS
func Environ]string
Environ returns a copyofstrings representing the environmentinthe
form"key=value".
func Getenv(key string)string
Getenv retrieves the valueofthe environment variable named by the key.
It returns the valueifthe variable isnot
present.
有了这个,就简单了。写了个简单的例子:
/self$ cat env"os"
func main{
environ=os.Environ=range environ(environ}
fmt"------------------------------------------------------------\n")
logname.Getenv"LOGNAME""logname is %s\n"}
输出如下:
/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
$pg_ctl-D /home/manu/DB_data/-l /home/manu/DB_data/postgres_manu.log start
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 类型
-W donotwaituntil 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"l""/home/manu/sample.log""log file")
nowait_flag.Bool"W""do not wait until operation completes")
flag.Parse)
var cmd string.Arg(0;
fmt"action : %s\n""data path: %s\n"*data_path"log file : %s\n"*log_file"nowait : %v\n"*nowait_flag"-------------------------------------------------------\n""there are %d non-flag input param\n".NArg=range flag"#%d:%s\n")
}
}
OK,我们分析下代码(
分割线下面的我们暂时不看):
第一行对应的是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
我们看到了,解析出了data_path,log_file无论 -l -D出现的顺序如何,只要正常的出现了,就能正常的解析。
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]
iflen(s||s'-'|len=1 {
return false
}
所以如果我们将non-flag参数放在最前面,flag什么也不会解析,因为flag遇到了这个就停止解析了。
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)
"#%d :%s\n")
}
flag还提供了NFlag()获取那些匹配上的参数的个数。
从例子上看,flag package很有用,但是并没有强大到解析一切的程度。
如果你有类似-option或者-key =value这种参数,不妨试试 flag。如果你的入参解析非常复杂,flag可能捉襟见肘。
参考文献:
1 标准库—命令行参数解析flag
2 Go 语言简介(下)— 特性 原文链接:https://www.f2er.com/go/190024.html