パスからファイル、ディレクトリ、リンクで処理を分ける
与えられたパスがファイルなのか、ディレクトリなのか、リンクなのかを調べるには、os.Stat(path string)でまずFileInfoを得ます。それから、FileInfo.Modeにos.Symlinkのフラグが立っていればリンク、ディレクトリの場合はIsDirで調べられます。
リンクからリンク元のパスを得るには、os.Readlink(path string)で調べられます。
package main import ( "fmt" "io/ioutil" "os" ) func PrintFileContent(f *os.File) { src, _ := ioutil.ReadAll(f) f.Close() fmt.Printf("%q\n", src) } func main() { args := os.Args[1:] if 1 != len(args) { fmt.Fprintf(os.Stderr, "usage:%s FILE|DIR|LINK\n", os.Args[0]) os.Exit(1) } finfo, err := os.Stat(args[0]) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } if finfo.Mode()&os.ModeSymlink != 0 { path, err := os.Readlink(args[0]) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } finfo, err = os.Stat(path) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } args[0] = path } if !finfo.IsDir() { f, err := os.Open(args[0]) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } PrintFileContent(f) return } else { list, err := ioutil.ReadDir(args[0]) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } for _, finfo := range list { if finfo.IsDir() { continue } path := fmt.Sprintf("%s%c%s", args[0], os.PathSeparator, finfo.Name()) f, err := os.Open(path) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } PrintFileContent(f) } } }