github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/os/env.go (about) 1 // Copyright 2010 The Go 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 // General environment variables. 6 7 package os 8 9 import "syscall" 10 11 // Expand replaces ${var} or $var in the string based on the mapping function. 12 // For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv). 13 func Expand(s string, mapping func(string) string) string { 14 buf := make([]byte, 0, 2*len(s)) 15 // ${} is all ASCII, so bytes are fine for this operation. 16 i := 0 17 for j := 0; j < len(s); j++ { 18 if s[j] == '$' && j+1 < len(s) { 19 buf = append(buf, s[i:j]...) 20 name, w := getShellName(s[j+1:]) 21 buf = append(buf, mapping(name)...) 22 j += w 23 i = j + 1 24 } 25 } 26 return string(buf) + s[i:] 27 } 28 29 // ExpandEnv replaces ${var} or $var in the string according to the values 30 // of the current environment variables. References to undefined 31 // variables are replaced by the empty string. 32 func ExpandEnv(s string) string { 33 return Expand(s, Getenv) 34 } 35 36 // isShellSpecialVar reports whether the character identifies a special 37 // shell variable such as $*. 38 func isShellSpecialVar(c uint8) bool { 39 switch c { 40 case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 41 return true 42 } 43 return false 44 } 45 46 // isAlphaNum reports whether the byte is an ASCII letter, number, or underscore 47 func isAlphaNum(c uint8) bool { 48 return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' 49 } 50 51 // getShellName returns the name that begins the string and the number of bytes 52 // consumed to extract it. If the name is enclosed in {}, it's part of a ${} 53 // expansion and two more bytes are needed than the length of the name. 54 func getShellName(s string) (string, int) { 55 switch { 56 case s[0] == '{': 57 if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' { 58 return s[1:2], 3 59 } 60 // Scan to closing brace 61 for i := 1; i < len(s); i++ { 62 if s[i] == '}' { 63 return s[1:i], i + 1 64 } 65 } 66 return "", 1 // Bad syntax; just eat the brace. 67 case isShellSpecialVar(s[0]): 68 return s[0:1], 1 69 } 70 // Scan alphanumerics. 71 var i int 72 for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { 73 } 74 return s[:i], i 75 } 76 77 // Getenv retrieves the value of the environment variable named by the key. 78 // It returns the value, which will be empty if the variable is not present. 79 func Getenv(key string) string { 80 v, _ := syscall.Getenv(key) 81 return v 82 } 83 84 // LookupEnv retrieves the value of the environment variable named 85 // by the key. If the variable is present in the environment the 86 // value (which may be empty) is returned and the boolean is true. 87 // Otherwise the returned value will be empty and the boolean will 88 // be false. 89 func LookupEnv(key string) (string, bool) { 90 return syscall.Getenv(key) 91 } 92 93 // Setenv sets the value of the environment variable named by the key. 94 // It returns an error, if any. 95 func Setenv(key, value string) error { 96 err := syscall.Setenv(key, value) 97 if err != nil { 98 return NewSyscallError("setenv", err) 99 } 100 return nil 101 } 102 103 // Unsetenv unsets a single environment variable. 104 func Unsetenv(key string) error { 105 return syscall.Unsetenv(key) 106 } 107 108 // Clearenv deletes all environment variables. 109 func Clearenv() { 110 syscall.Clearenv() 111 } 112 113 // Environ returns a copy of strings representing the environment, 114 // in the form "key=value". 115 func Environ() []string { 116 return syscall.Environ() 117 }