github.com/cilki/sh@v2.6.4+incompatible/shell/expand.go (about) 1 // Copyright (c) 2018, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 package shell 5 6 import ( 7 "os" 8 "strings" 9 10 "mvdan.cc/sh/expand" 11 "mvdan.cc/sh/syntax" 12 ) 13 14 // Expand performs shell expansion on s as if it were within double quotes, 15 // using env to resolve variables. This includes parameter expansion, arithmetic 16 // expansion, and quote removal. 17 // 18 // If env is nil, the current environment variables are used. Empty variables 19 // are treated as unset; to support variables which are set but empty, use the 20 // expand package directly. 21 // 22 // Command subsitutions like $(echo foo) aren't supported to avoid running 23 // arbitrary code. To support those, use an interpreter with the expand package. 24 // 25 // An error will be reported if the input string had invalid syntax. 26 func Expand(s string, env func(string) string) (string, error) { 27 p := syntax.NewParser() 28 word, err := p.Document(strings.NewReader(s)) 29 if err != nil { 30 return "", err 31 } 32 if env == nil { 33 env = os.Getenv 34 } 35 cfg := &expand.Config{Env: expand.FuncEnviron(env)} 36 return expand.Document(cfg, word) 37 } 38 39 // Fields performs shell expansion on s as if it were a command's arguments, 40 // using env to resolve variables. It is similar to Expand, but includes brace 41 // expansion, tilde expansion, and globbing. 42 // 43 // If env is nil, the current environment variables are used. Empty variables 44 // are treated as unset; to support variables which are set but empty, use the 45 // expand package directly. 46 // 47 // An error will be reported if the input string had invalid syntax. 48 func Fields(s string, env func(string) string) ([]string, error) { 49 p := syntax.NewParser() 50 var words []*syntax.Word 51 err := p.Words(strings.NewReader(s), func(w *syntax.Word) bool { 52 words = append(words, w) 53 return true 54 }) 55 if err != nil { 56 return nil, err 57 } 58 if env == nil { 59 env = os.Getenv 60 } 61 cfg := &expand.Config{Env: expand.FuncEnviron(env)} 62 return expand.Fields(cfg, words...) 63 }