通过Golang实现linux命令ls命令(命令行工具构建)

2023-01-14 09:57:22
目录
ls 命令os.Args 读取参数pflag小结

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命令行工具的资料请关注易采站长站其它相关文章!