前幾天在微博上看到有人推薦了lazygit這個工具,讓人眼前一亮,什么時候命令行也可以這么搶到了,🤣,調研了下,發現它使用了gocui,使用它可以做出來很多很炫的命令行工具。
現有的hosts工具里面也有switchosts!
,但我是用的時候發現他還是有bug,也只能用在界面化平台。想了下,准備着手搞一個命令行的hsots配置工具,這個類庫完全可以滿足。
界面設計
在界面設計上,還是做個copycat,抄襲switchosts!
的,分兩欄,左側是hosts分組,右邊兒是當前聚焦hosts分組內容,控制開關放在左側,如下所示。左側開關控制每個組的開啟關閉與否,系統當前的hosts是左側所有打開hosts的集合。
*------*-------------------*
|×name1|# hosts for name2 |
|√name2|1.1.1.1 a.com |
|×name3|0.0.0.0 abc.com |
| | |
| | |
| | |
*------*-------------------*
hosts實現原理
原理和switchosts!
的類似,通過修改系統hosts文件來達到目的,每次修改的變動都會實時的體現到系統hosts文件中,這樣就實現了控制hosts的目的。
hosts 配置軟件 系統hosts
*------*-------------------* *-------------------------*
|×name1|# hosts for name2 | |# hosts for name2 |
|√name2|1.1.1.1 a.com | |1.1.1.1 a.com |
|√name3|0.0.0.0 abc.com | |0.0.0.0 abc.com |
| | | => |# hosts for name3 |
| | | |127.0.0.1 localhost |
| | | | |
*------*-------------------* *-------------------------*
gocui為我們提供了什么
gocui是一個很強大的庫,就像他所說的那樣Go Console User Interface
,提供一個命令行用戶界面。他為我們賦予了控制刷新terminal的能力,比如將terminal分為多個view(分區),每個view可以獨立控制刷新,響應鍵盤的事件,所以,只要你願意,甚至可以做出一些簡單的小游戲。
gohosts
目前為止gohosts的功能基本已開發完成,主要有功能就是切換hosts,有如下交互:
- 聚焦左側view時,通過
shift + a
組合鍵,創建新的hosts分組。 - 通過
tab
鍵,切換左側、右側view。 - 聚焦彈層view時,當創建新的hosts分組的時候,會進入彈層view,輸入內容后,按下enter鍵生效。
- 聚焦左側view時,通過上下箭頭切換hosts分組。
- 聚焦左側view時候,通過左右箭頭切換hosts分組開關。
gohosts實現
因為要修改hosts,所以運行程序的時候也必須要使用root權限,初次運行的時候,會自動進行初始化,生成backup
分組,並將系統當前已有hosts內容放入其中。
gohosts的配置文件會放在運行用戶的家目錄下面的.gohost
文件夾下,每次啟動的時候,會從其中讀取配置文件,並展現出來。另外,為了做兼容,區分了windows系統和linux系統,通過getUserHome
函數獲取用戶家目錄。另外作為一個copycat,從switchosts!
哪里了解到,有的windows系統盤不裝在C盤,通過getWinSystemDir
獲取windows的系統盤目錄,做到盡可能的全平台、多環境兼容。
func getUserHome() string {
home := ""
if runtime.GOOS == "windows" {
home = os.Getenv("USERPROFILE")
} else {
home = os.Getenv("HOME")
}
return home
}
func getWinSystemDir() string {
dir := ""
if runtime.GOOS == "windows" {
dir = os.Getenv("windir")
}
return dir
}
另外這里2次使用了go協程來檢驗語法,啟動軟件的時候,啟動協程,每隔50ms檢測一次輸入的內容是否合規,如下所示,協程中是個死循環,如果不合規,標紅展示。
go func() {
for range time.Tick(time.Millisecond * 50) {
// do something
}
}()
比如我們輸入hosts配置的時候,必須滿足下面3中正則,不然會提示哪一行有錯誤。
"^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}(?:[ ]{1,})(?:[ 0-9a-zA-Z._-]{1,}){1,}$"
"^[ ]*$"
"^#.*"
還有我們輸入新建hosts分組的時候,如果hosts分組名字已經存在了,或者hosts分組名字超過長度了,也會在輸入彈層view中提示標紅。
golang的協程處理這些內容簡直得天獨厚,處理起來很輕松,也很簡單高效。
另外比較麻煩的地方就是控制光標焦點了,左側增加hosts分組的時候,還有當分組個數超過最大顯示行數的時候,這就相當用畫布、畫框的情況,當移動焦點的時候,需要對應的做出移動畫布還是移動畫框,哈哈,有興趣的可以看看代碼中的邏輯。
gohosts效果展示
總結
自己已經實際使用了幾天了,還算好用,比較遺憾的就是不支持中文,中文會出現顯示不全的問題,這是依賴庫導致的,改起來估計比較費勁,不過對於hosts來說,全英文也沒問題。
原文鏈接:
http://www.5aikid.com/2018/08/23/gohost-go-開發的命令行hosts配置管理工具/
github地址:
https://github.com/aizuyan/gohosts
另外這是第一次真正的使用golang做出一些有用的東西,感覺還挺不錯,准備稍微閑點兒了,好好研究下這個
依賴庫gocui。