package main import ( "flag" "fmt" "os" "path/filepath" "time" ) var verbos = flag.Bool("v",false,"show verbose") func main() { flag.Parse() roots := flag.Args() if len(roots) == 0 { roots = []string{"."} } fileSizes := make(chan int64) go func() { for _,root := range roots { WalkDir(root,fileSizes) } close(fileSizes) }() var tick <- chan time.Time if *verbos{ tick = time.Tick(500 * time.Millisecond) } var nfiles,nbytes int64 loop: for { select { case size,ok := <- fileSizes: if !ok { break loop } nfiles++ nbytes += size case <- tick: printDU(nfiles,nbytes) } } } func printDU(nfiles, nbytes int64) { fmt.Printf("%d files, %.1f GB\n",nfiles,float64(nbytes)/1e9) } func WalkDir(dir string, fileSizes chan <- int64) { for _, entry := range dirents(dir) { if entry.IsDir() { subdir := filepath.Join(dir,entry.Name()) WalkDir(subdir,fileSizes) } else { size,_ := entry.Info() fileSizes <- size.Size() } } } func dirents(dir string) []os.DirEntry{ entries, err := os.ReadDir(dir) if err != nil { fmt.Fprintf(os.Stderr,"du1: %v\n",err) return nil } return entries }