首頁 > 軟體

通過Golang實現linux命令ls命令(命令列工具構建)

2023-01-14 14:01:27

ls 命令

要實現ls,首先先我們複習一下ls命令。

  • ls不加任何引數,表示查詢當前目錄下的檔案/資料夾
  • ls後面加上路徑,列出所有,不包含隱藏檔案/資料夾
  • ls -a列出所有,包括以.開頭的隱藏檔案

此命令還有很多功能,這一節的重點是命令列程度的編寫,就實現上面四個。

os.Args 讀取引數

定義如下,一個陣列。該陣列長度由引數個數決定,第一個引數為程式本身,後面為參數列。

var Args []string

比如ls -lArgs=["ls","-l"],我們現在實現ls+目錄,或者預設目錄時預設當前目錄程式碼如下。

func main() {
	targetDirPath := "./"
	if len(os.Args) > 1 {
		targetDirPath = os.Args[1]
	}

	if dirList, err := ioutil.ReadDir(targetDirPath); err == nil {
		for _, dirInfo := range dirList {
			fmt.Print(dirInfo.Name() + " ")
		}
	} else {
		fmt.Println(err.Error())
	}
}
  • 使用 os.Agrs 來獲取傳入程式的引數
  • 使用 ioutil.ReadDir 讀取目錄,將返回值[] FileInfo遍歷,輸出目錄/檔案資訊
  • 將遇到的error輸出到 終端

輸出

$ go build -o ls main.go
$ ./ls 
main.go folder ls
$ ./ls folder
file1 file2

看,我們已經簡單的實現了。但我們會發現,要使用-開頭的引數時,用os.Args這個還需要手寫更多複雜邏輯去判斷輸入的到底是路徑,還是其他引數,於是下一個包登場了。

pflag

昨天的每日一Go已經講了flag包,pflag 包與 flag 包的工作原理甚至是程式碼實現都是類似的,下面是 pflag 相對 flag 的一些優勢:

  • 支援更加精細的引數型別:例如,flag 只支援 uintuint64,而 pflag 額外支援 uint8uint16int32 等型別。
  • 支援更多引數型別:ipip maskip netcount、以及所有型別的 slice 型別。
  • 相容標準 flag 庫的 FlagFlagSetpflag 更像是對 flag 的擴充套件。
  • 原生支援更豐富的功能:支援 shorthanddeprecatedhidden 等高階功能。
var a = pflag.BoolP("all", "a", false, "Include directory entries whose names begin with a dot (.).")
	var help = pflag.BoolP("help", "h", false, "Show this help message.")
	pflag.Parse()
	if *help {
		pflag.Usage()
		return
	}
	args := pflag.Args()
	if len(args) == 0 {
		args = append(args, "./")
	}
	if len(args) == 1 {
		ShowPath(args[0], *a)
	} else {
		for _, v := range args {
			fmt.Println(v + ":")
			ShowPath(v, *a)
		}
	}
  • 列出資料夾的方式寫到了ShowPath函數裡,第二引數是一個bool判斷是否列出全部檔案(包括隱藏檔案)感興趣去看我原始碼,這裡不是重點。
  • pflag.BoolP 定義一個bool型別的引數,支援長短引數形式--all,-a,返回值是指標。
  • pflag.Parse() 呼叫這個函數,把引數值設定到相應指標的指向裡。
  • pflag.Usage() 用法列印。

這樣我們就實現了ls的基本功能。測試一下。

$ go build -o ls main.go
$ ./ls
folder go.mod go.sum main.go 
$ ./ls -a
. .. .git folder go.mod go.sum main.go 
$ ./ls ./ folder 
./:
folder go.mod go.sum main.go 
folder:
file1 file2
$ ./ls -h
Usage of ./ls:
  -a, --all    Include directory entries whose names begin with a dot (.).
  -h, --help   Show this help message.

是不是相當給力啦!

小結

命令列讀取一共有五個常用的包

  • os.Args 系統包提供的引數解析。
  • flag:簡單引數解析,昨天的每日一Go分享過。
  • pflag:命令列引數解析。
  • cobra:應用命令列框架,改天再分享。
  • viper:組態檔、環境變數、命令列、緩衝區。今天群裡的每日一Go已經分享了,就不多說了。

命令列工具,你只要賦予可執行許可權,再放到bin裡面,他就會成為一個系統命令,方便你做更多的事情,比如備份資料庫之類的動作,提高你的運維效率。 哦對了原始碼在這:https://github.com/golang-minibear2333/cmd_utils

以上就是通過Golang實現linux命令ls命令(命令列工具構建)的詳細內容,更多關於Golang命令列工具的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com