在 Go 中構建網路命令列介面
在本文中,我們將使用Github
上提供的軟體包urfave/cli
在 Go 中構建一個非常簡單的命令列介面,軟體包位於 https://github.com/urfave/cli。
我最近在各種託管服務提供商中進行了一次或兩次域名遷移,並認為構建一個可用於查詢網站名稱伺服器,CNAME,IP 地址等內容的工具或程式是一個很酷的主意。
本教程的總體目標是讓您瞭解如何構建自己的 CLI,這些 CLI 可以執行各種其他操作,例如網路監視,影象處理等。
注 - 可在此處找到本教程的完整程式碼:TutorialEdge/Go/go-cli-tutorial
熱門專案
Golang
正在大規模普及,我們已經看到像Hashicorp
這樣的大型企業公司採用了許多不同工具和系統的語言。而且有充分的理由相信Go
的設計非常適合這些應用程式,並且能夠其能夠輕鬆地為所有主要平臺跨平臺編譯成二進位制可執行檔案將會是一個巨大的勝利。
視訊教程
如果您更喜歡通過視訊媒體進行學習,請隨時檢視本教程:視訊地址
入門
讓我們在我們的計算機上建立一個新目錄,命名為go-cli
或者其他。我們將為我們的專案建立一個類似於此的目錄結構:
go-cli/ - pkg/ - cmd/my-cli/ - vendor/ - README.md - ...
注意 - 此結構遵循 Github 上廣泛接受的Go 專案佈局 指南。
進入程式碼
現在我們已經有了基本的專案結構,我們可以開始編寫我們的應用程式了。首先,我們需要在cmd/my-cli/
的目錄內建立一個新檔案cli.go
。我們編寫一種非常簡單的語句Hello World
,並將其作為我們未來開發的基礎。
// cmd/my-cli/cli.go package main import ( "fmt" ) func main() { fmt.Println("Go CLI v0.01") }
然後我們可以 在專案的根目錄通過輸入以下命令嘗試執行它:
➜ Go run cmd/my-cli/cli.go Go CLI v0.01
很好,我們已經對新 CLI 的要素進行了理解,讓我們現在看看我們如何新增一些命令並使其有用。
我們的第一命令
由於我們將使用urfave/cli
軟體包,我們需要在本地下載此軟體包才能使用它,我們可以通過一個簡單的go get
命令來實現:
go get Github.com/urfave/cli
現在我們有了必要的包,讓我們更新我們的cli.go
檔案並使用這個包為我們建立一個新的 CLI 應用程式:
// cmd/my-cli/cli.go import ( "log" "os" "github.com/urfave/cli" ) func main() { err := cli.NewApp().Run(os.Args) if err != nil { log.Fatal(err) } }
當我們現在執行它時,你會看到它豐富了我們的程式響應並添加了諸如版本,如何使用 cli 以及擁有的各種命令之類的東西。
➜Go run cmd/my-cli/cli.go NAME: cli - A new cli application USAGE: cli [global options] command [command options] [arguments...] VERSION: 0.0.0 COMMANDS: help, hShows a list of commands or help for one command GLOBAL OPTIONS: --help, -hshow help --version, -vprint the version
太棒了,這很快就開始看起來像一個更精美的專案,而不僅僅是一個小方案專案!
我們現在可以開始新增我們自己的Commands
。這些命令中的每一個都將與我們的一個測試相匹配,因此我們將有一個命令:ns
當提供一個 url 執行時將開始查詢該 url 主機的域名伺服器。
我們的最終命令列表將如下所示:
- ns - 將檢索域名伺服器
- cname - 將查詢給定主機的 CNAME
- mx - 將查詢給定主機的郵件交換記錄
- ip - 將查詢給定主機的 IP 地址。
很好很簡單,讓我們開始建立我們的第一個命令:
package main import ( "fmt" "log" "net" "os" "github.com/urfave/cli" ) func main() { app := cli.NewApp() app.Name = "Website Lookup CLI" app.Usage = "Let's you query IPs, CNAMEs, MX records and Name Servers!" // We'll be using the same flag for all our commands // so we'll define it up here myFlags := []cli.Flag{ cli.StringFlag{ Name:"host", Value: "tutorialedge.net", }, } // we create our commands app.Commands = []cli.Command{ { Name:"ns", Usage: "Looks Up the NameServers for a Particular Host", Flags: myFlags, // the action, or code that will be executed when // we execute our `ns` command Action: func(c *cli.Context) error { // a simple lookup function ns, err := net.LookupNS(c.String("url")) if err != nil { return err } // we log the results to our console // using a trusty fmt.Println statement for i := 0; i < len(ns); i++ { fmt.Println(ns[i].Host) } return nil }, }, } // start our application err := app.Run(os.Args) if err != nil { log.Fatal(err) } }
然後我們可以通過輸入以下命令來嘗試執行:
go run cmd/my-cli/cli.go ns --url tutorialedge.net
然後,這應該返回我的站點的域名伺服器並在終端中打印出來。我們還可以執行 help 命令,它將向我們展示如何在 CLI 中使用我們的新命令。
查詢 IP 地址
我們的所有命令定義在我們的程式中看起來都非常相似,除了我們如何打印出結果。net.LookupIP()
函式返回一系列 IP 地址,因此我們必須迭代這些地址以便以一種很好的方式列印它們:
{ Name:"ip", Usage: "Looks up the IP addresses for a particular host", Flags: myFlags, Action: func(c *cli.Context) error { ip, err := net.LookupIP(c.String("host")) if err != nil { fmt.Println(err) } for i := 0; i < len(ip); i++ { fmt.Println(ip[i]) } return nil }, },
查詢 CNAME
然後我們可以新增我們的cname
命令,它將使用net.LookupCNAME()
接受傳入host
中的資料並返回一個CNAME
字串,接下來我們可以打印出來:
{ Name:"cname", Usage: "Looks up the CNAME for a particular host", Flags: myFlags, Action: func(c *cli.Context) error { cname, err := net.LookupCNAME(c.String("host")) if err != nil { fmt.Println(err) } fmt.Println(cname) return nil }, },
查詢 MX 記錄
最後,我們希望能夠查詢給定主機的Mail Exchange
記錄,我們可以通過使用net.LookupMX()
函式並傳入host
資料來實現。這將返回一片 mx 記錄,和 IP 一樣,我們必須迭代才能打印出來
{ Name:"mx", Usage: "Looks up the MX records for a particular host", Flags: myFlags, Action: func(c *cli.Context) error { mx, err := net.LookupMX(c.String("host")) if err != nil { fmt.Println(err) } for i := 0; i < len(mx); i++ { fmt.Println(mx[i].Host, mx[i].Pref) } return nil }, },
構建我們的 CLI
現在我們已經啟動並運行了一個基本的 CLI,現在是時候構建它,以便我們可以直接使用它。
go build cmd/my-cli/cli.go
這應該編譯一個名稱為cli
可執行檔案,我們可以這樣執行它:
$ ./cli help NAME: Website Lookup CLI - Let's you query IPs, CNAMEs, MX records and Name Servers! USAGE: cli [global options] command [command options] [arguments...] VERSION: 0.0.0 COMMANDS: nsLooks Up the NameServers for a Particular Host cnameLooks up the CNAME for a particular host ipLooks up the IP addresses for a particular host mxLooks up the MX records for a particular host help, hShows a list of commands or help for one command GLOBAL OPTIONS: --help, -hshow help --version, -vprint the versio
如您所見,我們的所有命令都已成功列在輸出的COMMANDS
中。
結論
在本教程中,我們使用urface/cli
軟體包成功構建了一個非常簡單但有效的 CLI。該 CLI 可以非常簡單的針對任何主要作業系統進行跨平臺的編譯,並且它具有您期望從生產級命令列介面獲得的所有功能。
注意 - 如果您想了解網站上的最新文章和更新,請隨時在 Twitter 上關注我:@Elliot_f