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  }