golang实现一个linux命令ls命令(命令行工具构建)

2023-01-11  本文已影响0人  机智的程序员小熊

希望2023可以听到这些话:

在这篇文章下面许个愿吧!

ls 命令

要实现ls,首先先我们复习一下ls命令。

此命令还有很多功能,这一节的重点是命令行程度的编写,就实现上面四个。

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())
    }
}

输出

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

看,我们已经简单的实现了。但我们会发现,要使用-开头的参数时,用os.Args这个还需要手写更多复杂逻辑去判断输入的到底是路径,还是其他参数,于是下一个包登场了。

pflag

昨天的每日一Go已经讲了flag包,pflag 包与 flag 包的工作原理甚至是代码实现都是类似的,下面是 pflag 相对 flag 的一些优势:

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)
        }
    }

这样我们就实现了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.

是不是相当给力啦!

小结

命令行读取一共有五个常用的包

命令行工具,你只要赋予可执行权限,再放到bin里面,他就会成为一个系统命令,方便你做更多的事情,比如备份数据库之类的动作,提高你的运维效率。

引用

本文由mdnice多平台发布

上一篇 下一篇

猜你喜欢

热点阅读