github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/readlink/readlink.go (about) 1 // Copyright 2013-2022 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // readlink display value of symbolic link file. 6 // 7 // Synopsis: 8 // 9 // readlink [OPTIONS] [FILE...] 10 // 11 // Options: 12 // 13 // -f: follow 14 // -n: nonewline 15 // -v: verbose 16 package main 17 18 import ( 19 "flag" 20 "fmt" 21 "io" 22 "os" 23 "path/filepath" 24 ) 25 26 const cmd = "readlink [-fnv] FILE" 27 28 var ( 29 follow = flag.Bool("f", false, "follow recursively") 30 noNewLine = flag.Bool("n", false, "do not output trailing newline") 31 verbose = flag.Bool("v", false, "report error messages") 32 ) 33 34 func init() { 35 defUsage := flag.Usage 36 flag.Usage = func() { 37 os.Args[0] = cmd 38 defUsage() 39 } 40 } 41 42 func readLink(stdout io.Writer, file string) error { 43 path, err := os.Readlink(file) 44 if err != nil { 45 return err 46 } 47 48 if *follow { 49 path, err = filepath.EvalSymlinks(file) 50 } 51 52 delimiter := "\n" 53 if *noNewLine { 54 delimiter = "" 55 } 56 57 fmt.Fprintf(stdout, "%s%s", path, delimiter) 58 return err 59 } 60 61 func run(stdout io.Writer, stderr io.Writer, args []string) error { 62 if len(args) == 0 { 63 if *verbose { 64 fmt.Fprintf(stderr, "missing operand") 65 } 66 return fmt.Errorf("missing operand") 67 } 68 69 var runErr error 70 for _, file := range args { 71 err := readLink(stdout, file) 72 if err != nil { 73 if *verbose { 74 fmt.Fprintf(stderr, "%v\n", err) 75 } 76 runErr = err 77 } 78 } 79 80 return runErr 81 } 82 83 func main() { 84 flag.Parse() 85 if err := run(os.Stdin, os.Stderr, flag.Args()); err != nil { 86 os.Exit(1) 87 } 88 }