4.命令行工具
截至目前我们区块链的基本逻辑已经构建完毕,现在我们使用命令行工具按照我们想要的目的进行输出
4.1 flag基本使用
在此之前,我们先来看看flag的基本使用方法
/Users/xxx/go/src/publicChain/part21-cli-flag/main.go
package main
import (
"flag"
"fmt"
)
func main() {
flagString := flag.String("printChain", "", "output all details of blocks")
flagInt := flag.Int("number", 6, "output an int")
flagBool := flag.Bool("open", false, "Judging true and false")
flag.Parse()
fmt.Printf("%s\n", *flagString)
fmt.Printf("%d\n", *flagInt)
fmt.Printf("%t\n", *flagBool)
}
在终端构建程序并运行
cd /Users/xxx/go/src/publicChain/part21-cli-flag
go build main.go
./main
输出结果
6
false
通过-输出指定内容,指定的顺序可以变化
./main -printChain "jech" -open -number 10
jech
10
true
4.2 os
我们再来看一个os包下面的变量args
/Users/xxx/go/src/publicChain/part22-cli-osArgs/main.go
func main() {
args := os.Args
fmt.Printf("%v\n", args)
}
go build main.go
./main printChain -data "jech.org"
[./main printChain -data jech.org]
它能够将输入连接成一个数组,这个数组中的元素可以随着输入无限增长
./main how are you
[./main how are you]
当然我们可以对这个动态数组求长度、访问里面的元素等
4.3 命令行解释器
现在我们结合os包下的变量args和flag实现我们自定义的命令行工具。args可以获取输入,通过一定的解析可以实现自定义的命令行工具,我们来看看具体代码实现:
/Users/xxx/go/src/publicChain/part23-cli/main.go
func printUsage() {
fmt.Println("Usage:")
fmt.Println("\taddBlock -data DATA - transaction data")
fmt.Println("\tprintChain -- output block's information")
}
func isValidArgs() {
if len(os.Args) < 2 {
printUsage()
os.Exit(1)
}
}
func main() {
isValidArgs()
//custom command
addBlockCmd := flag.NewFlagSet("addBlock", flag.ExitOnError)
printChainCmd := flag.NewFlagSet("printChain", flag.ExitOnError)
flagAddBlockData := addBlockCmd.String("data", "jech.org", "transaction data...")
switch os.Args[1] {
case "addBlock":
err := addBlockCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "printChain":
err := printChainCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
default:
printUsage()
os.Exit(1)
}
if addBlockCmd.Parsed() {
if *flagAddBlockData == "" {
printUsage()
os.Exit(1)
}
fmt.Println(*flagAddBlockData)
cli.addBlock(*flagAdd