Golang實現(xiàn)一個linux命令ls命令(命令行工具構(gòu)建)

希望2023可以聽到這些話:
- 恭喜你得到了這份工作
- 恭喜你的建議被采用了
- 恭喜你被錄取了
- 恭喜你的考試順利通過了
- 恭喜你上岸了
- 恭喜你升職了
- 恭喜你加薪了
- 恭喜你體檢結(jié)果一切正常
在這篇文章下面許個愿吧!
ls 命令
要實現(xiàn)ls,首先先我們復(fù)習(xí)一下ls命令。
-
ls不加任何參數(shù),表示查詢當(dāng)前目錄下的文件/文件夾 -
ls后面加上路徑,列出所有,不包含隱藏文件/文件夾 -
ls -a列出所有,包括以.開頭的隱藏文件
此命令還有很多功能,這一節(jié)的重點是命令行程度的編寫,就實現(xiàn)上面四個。
os.Args 讀取參數(shù)
定義如下,一個數(shù)組。該數(shù)組長度由參數(shù)個數(shù)決定,第一個參數(shù)為程序本身,后面為參數(shù)列表。
var?Args?[]string
比如ls -l,Args=["ls","-l"],我們現(xiàn)在實現(xiàn)ls+目錄,或者缺省目錄時默認當(dāng)前目錄代碼如下。
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來獲取傳入程序的參數(shù) -
使用
ioutil.ReadDir讀取目錄,將返回值[] FileInfo遍歷,輸出目錄/文件信息 -
將遇到的
error輸出到 終端
輸出
$?go?build?-o?ls?main.go
$?./ls?
main.go?folder?ls
$?./ls?folder
file1?file2
看,我們已經(jīng)簡單的實現(xiàn)了。但我們會發(fā)現(xiàn),要使用-開頭的參數(shù)時,用os.Args這個還需要手寫更多復(fù)雜邏輯去判斷輸入的到底是路徑,還是其他參數(shù),于是下一個包登場了。
pflag
昨天的每日一Go已經(jīng)講了flag包,pflag 包與 flag 包的工作原理甚至是代碼實現(xiàn)都是類似的,下面是 pflag 相對 flag 的一些優(yōu)勢:
-
支持更加精細的參數(shù)類型:例如,
flag只支持uint和uint64,而pflag額外支持uint8、uint16、int32等類型。 -
支持更多參數(shù)類型:
ip、ip mask、ip net、count、以及所有類型的slice類型。 -
兼容標(biāo)準(zhǔn)
flag庫的Flag和FlagSet:pflag更像是對flag的擴展。 -
原生支持更豐富的功能:支持
shorthand、deprecated、hidden等高級功能。
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函數(shù)里,第二參數(shù)是一個bool判斷是否列出全部文件(包括隱藏文件)感興趣去看我源代碼,這里不是重點。 -
pflag.BoolP定義一個bool類型的參數(shù),支持長短參數(shù)形式--all,-a,返回值是指針。 -
pflag.Parse()調(diào)用這個函數(shù),把參數(shù)值設(shè)置到相應(yīng)指針的指向里。 -
pflag.Usage()用法打印。
這樣我們就實現(xiàn)了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.
是不是相當(dāng)給力啦!
小結(jié)
命令行讀取一共有五個常用的包
-
os.Args系統(tǒng)包提供的參數(shù)解析。 -
flag:簡單參數(shù)解析,昨天的每日一Go分享過。 -
pflag:命令行參數(shù)解析。 -
cobra:應(yīng)用命令行框架,改天再分享。 -
viper:配置文件、環(huán)境變量、命令行、緩沖區(qū)。今天群里的每日一Go已經(jīng)分享了,就不多說了。
命令行工具,你只要賦予可執(zhí)行權(quán)限,再放到bin里面,他就會成為一個系統(tǒng)命令,方便你做更多的事情,比如備份數(shù)據(jù)庫之類的動作,提高你的運維效率。
評論
圖片
表情
