github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/mktemp/mktemp.go (about) 1 // Copyright 2012-2018 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 // Mktemp makes a temporary file (or directory) 6 // 7 // Synopsis: 8 // mktemp [OPTION]... [TEMPLATE] 9 // 10 // Create a temporary file or directory, safely, and print its name. TEMPLATE must contain at least 3 consecutive 'X's in last component. If TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied. Files are 11 // created u+rw, and directories u+rwx, minus umask restrictions. 12 // 13 // -d, --directory 14 // create a directory, not a file 15 // 16 // -u, --dry-run 17 // do not create anything; merely print a name (unsafe) 18 // 19 // -q, --quiet 20 // suppress diagnostics about file/dir-creation failure 21 // 22 // --suffix=SUFF 23 // append SUFF to TEMPLATE; SUFF must not contain a slash. This option is implied if TEMPLATE does not end in X 24 // 25 // -p DIR, --tmpdir[=DIR] 26 // interpret TEMPLATE relative to DIR; if DIR is not specified, use $TMPDIR if set, else /tmp. With this option, TEMPLATE must not be an absolute name; unlike with -t, TEMPLATE may contain slashes, but mktemp creates 27 // only the final component 28 package main 29 30 import ( 31 "fmt" 32 "io/ioutil" 33 "log" 34 "os" 35 "strings" 36 37 flag "github.com/spf13/pflag" 38 ) 39 40 type mktempflags struct { 41 d bool 42 u bool 43 q bool 44 v bool 45 prefix string 46 suffix string 47 dir string 48 } 49 50 var ( 51 flags mktempflags 52 ) 53 54 func init() { 55 flag.BoolVarP(&flags.d, "directory", "d", false, "Make a directory") 56 flag.BoolVarP(&flags.u, "dry-run", "u", false, "Do everything save the actual create") 57 flag.BoolVarP(&flags.v, "quiet", "q", false, "Quiet: show no errors") 58 flag.StringVarP(&flags.prefix, "prefix", "s", "", "add a prefix -- the s flag is for compatibility with GNU mktemp") 59 flag.StringVarP(&flags.suffix, "suffix", "", "", "add a suffix to the prefix (rather than the end of the mktemp file)") 60 flag.StringVarP(&flags.dir, "tmpdir", "p", "", "Tmp directory to use. If this is not set, TMPDIR is used, else /tmp") 61 } 62 63 func usage() { 64 log.Fatalf("Usage: mktemp [options] [template]\n%v", flag.CommandLine.FlagUsages()) 65 } 66 67 func mktemp() (string, error) { 68 if flags.dir == "" { 69 flags.dir = os.Getenv("TMPDIR") 70 } 71 72 if flags.u { 73 if !flags.q { 74 log.Printf("Not doing anything but dry-run is an inherently unsafe concept") 75 } 76 return "", nil 77 } 78 79 if flags.d { 80 d, err := ioutil.TempDir(flags.dir, flags.prefix) 81 return d, err 82 } 83 f, err := ioutil.TempFile(flags.dir, flags.prefix) 84 return f.Name(), err 85 } 86 87 func main() { 88 flag.Parse() 89 90 args := flag.Args() 91 92 switch len(args) { 93 case 1: 94 // To make this work, we strip the trailing X's, since the Go runtime doesn't work 95 // as old school mktemp(3) does. Just split on the first X. 96 // If they also specified a suffix, well, add that to the prefix I guess. 97 flags.prefix = flags.prefix + strings.Split(args[0], "X")[0] + flags.suffix 98 case 0: 99 default: 100 usage() 101 } 102 103 fileName, err := mktemp() 104 if err != nil && !flags.q { 105 log.Fatalf("%v", err) 106 } 107 fmt.Println(fileName) 108 }