This is a creation in Article, where the information may have evolved or changed.
We casually write a daily use of the Psql command line usage
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
In this case, we need to parse the meaning of each parameter, such as the-D option is to notify the path of Pg_ctl Pgdata, the-l option tells the log log to that file, and start is tantamount to a subcommand telling the action. For this kind of command, we all know that C language has getopt and its getopt_long to solve. How to solve the go language?
The go language provides the flag of this package. To deal with the parsing of such an entry.
The language format supported by flag is as follows:
-flag//BOOL type only
-flag=x
-flag x//not bool Type
Naturally, this flag can parse the-d/home/manu/db_data, corresponding to the second type, we know that the PG_CTL has the-w option, which belongs to the option of a switch-nature bool Type
View Sourceprint?
1.
-W
do
not wait
until
operation completes
Nature corresponds to the first type and can also be resolved. The second kind is also very well understood.
Below I give an example, simple parse this pg_ctl command:
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 : %s\n"
,cmd)
21.
fmt.Printf(
"data path: %s\n"
,*data_path)
22.
fmt.Printf(
"log file : %s\n"
,*log_file)
23.
fmt.Printf(
"nowait : %v\n"
,*nowait_flag)
24.
25.
fmt.Printf(
"-------------------------------------------------------\n"
)
26.
27.
fmt.Printf(
"there are %d non-flag input param\n"
,flag.NArg())
28.
for
i,param := range flag.Args(){
29.
fmt.Printf(
"#%d :%s\n"
,i,param)
30.
}
31.
32.
33.
}
OK, let's Analyze the code (below the split line we don't see for the moment):
The first line corresponds to the parsing rules of the Data_path
The value corresponding to the-D option is a string of type
The default value is "/home/manu/sample",
The DB data path hint or help message or description is.
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
We see, resolved the Data_path,log_file no matter how the order of-l-d appear, as long as the normal appearance, it can be normal analysis.
But there is also a cloud in the clear sky, start is not this type of-key=alue or-option, flag is unable to parse. We call this parameter the Non-flag parameter, and the flag parse stops when it encounters the Non-flag parameter:
View Sourceprint?
1.
s := f.args[0]
2.
if
len(s) == 0 || s[0] !=
'-'
|| len(s) == 1 {
3.
return
false
, nil
4.
}
So if we put the Non-flag parameter at the front, flag will not parse anything because flag will stop parsing when it encounters this.
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 provides ARG (i), Args () to get the Non-flag parameter, Narg () to get the number of Non-flag. As we see in the sample code.
View Sourceprint?
1.
fmt.Printf(
"there are %d non-flag input param\n"
,flag.NArg())
2.
for
i,param := range flag.Args(){
3.
fmt.Printf(
"#%d :%s\n"
,i,param)
4.
}
Flag also provides Nflag () to get the number of parameters on those matches.
From the example, the flag package is useful, but not strong to the extent of parsing everything.
If you have a parameter like-option or-key =value, you might want to try flag. If your entry parsing is complex, flag may be stretched.