diff --git a/variables.go b/variables.go
index 583b7467..eb936c59 100644
--- a/variables.go
+++ b/variables.go
@@ -21,36 +21,63 @@ var (
 	ErrMultilineResultCmd = errors.New("Got multiline result from command")
 )
 
-func (e *Executor) handleDynamicVariableContent(value string) (string, error) {
-	if !strings.HasPrefix(value, "$") {
-		return value, nil
+var templateFuncs template.FuncMap
+
+func init() {
+	taskFuncs := template.FuncMap{
+		"OS":   func() string { return runtime.GOOS },
+		"ARCH": func() string { return runtime.GOARCH },
+		// historical reasons
+		"IsSH": func() bool { return true },
+		"FromSlash": func(path string) string {
+			return filepath.FromSlash(path)
+		},
+		"ToSlash": func(path string) string {
+			return filepath.ToSlash(path)
+		},
+		"ExeExt": func() string {
+			if runtime.GOOS == "windows" {
+				return ".exe"
+			}
+			return ""
+		},
 	}
 
-	e.muDynamicCache.Lock()
-	defer e.muDynamicCache.Unlock()
-	if result, ok := e.dynamicCache[value]; ok {
-		return result, nil
+	templateFuncs = sprig.TxtFuncMap()
+	for k, v := range taskFuncs {
+		templateFuncs[k] = v
+	}
+}
+
+// ReplaceVariables writes vars into initial string
+func (e *Executor) ReplaceVariables(initial string, call Call) (string, error) {
+	vars, err := e.getVariables(call)
+	if err != nil {
+		return "", err
 	}
 
-	var stdout bytes.Buffer
-	opts := &execext.RunCommandOptions{
-		Command: strings.TrimPrefix(value, "$"),
-		Dir:     e.Dir,
-		Stdout:  &stdout,
-		Stderr:  e.Stderr,
-	}
-	if err := execext.RunCommand(opts); err != nil {
-		return "", &dynamicVarError{cause: err, cmd: opts.Command}
+	templ, err := template.New("").Funcs(templateFuncs).Parse(initial)
+	if err != nil {
+		return "", err
 	}
 
-	result := strings.TrimSuffix(stdout.String(), "\n")
-	if strings.ContainsRune(result, '\n') {
-		return "", ErrMultilineResultCmd
+	var b bytes.Buffer
+	if err = templ.Execute(&b, vars); err != nil {
+		return "", err
 	}
+	return b.String(), nil
+}
 
-	result = strings.TrimSpace(result)
-	e.verbosePrintfln(`task: dynamic variable: "%s", result: "%s"`, value, result)
-	e.dynamicCache[value] = result
+// ReplaceSliceVariables writes vars into initial string slice
+func (e *Executor) ReplaceSliceVariables(initials []string, call Call) ([]string, error) {
+	result := make([]string, len(initials))
+	for i, s := range initials {
+		var err error
+		result[i], err = e.ReplaceVariables(s, call)
+		if err != nil {
+			return nil, err
+		}
+	}
 	return result, nil
 }
 
@@ -85,66 +112,6 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
 	return result, nil
 }
 
-var templateFuncs template.FuncMap
-
-func init() {
-	taskFuncs := template.FuncMap{
-		"OS":   func() string { return runtime.GOOS },
-		"ARCH": func() string { return runtime.GOARCH },
-		// historical reasons
-		"IsSH": func() bool { return true },
-		"FromSlash": func(path string) string {
-			return filepath.FromSlash(path)
-		},
-		"ToSlash": func(path string) string {
-			return filepath.ToSlash(path)
-		},
-		"ExeExt": func() string {
-			if runtime.GOOS == "windows" {
-				return ".exe"
-			}
-			return ""
-		},
-	}
-
-	templateFuncs = sprig.TxtFuncMap()
-	for k, v := range taskFuncs {
-		templateFuncs[k] = v
-	}
-}
-
-// ReplaceSliceVariables writes vars into initial string slice
-func (e *Executor) ReplaceSliceVariables(initials []string, call Call) ([]string, error) {
-	result := make([]string, len(initials))
-	for i, s := range initials {
-		var err error
-		result[i], err = e.ReplaceVariables(s, call)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return result, nil
-}
-
-// ReplaceVariables writes vars into initial string
-func (e *Executor) ReplaceVariables(initial string, call Call) (string, error) {
-	vars, err := e.getVariables(call)
-	if err != nil {
-		return "", err
-	}
-
-	templ, err := template.New("").Funcs(templateFuncs).Parse(initial)
-	if err != nil {
-		return "", err
-	}
-
-	var b bytes.Buffer
-	if err = templ.Execute(&b, vars); err != nil {
-		return "", err
-	}
-	return b.String(), nil
-}
-
 // GetEnvironmentVariables returns environment variables as map
 func getEnvironmentVariables() Vars {
 	var (
@@ -159,3 +126,36 @@ func getEnvironmentVariables() Vars {
 	}
 	return m
 }
+
+func (e *Executor) handleDynamicVariableContent(value string) (string, error) {
+	if !strings.HasPrefix(value, "$") {
+		return value, nil
+	}
+
+	e.muDynamicCache.Lock()
+	defer e.muDynamicCache.Unlock()
+	if result, ok := e.dynamicCache[value]; ok {
+		return result, nil
+	}
+
+	var stdout bytes.Buffer
+	opts := &execext.RunCommandOptions{
+		Command: strings.TrimPrefix(value, "$"),
+		Dir:     e.Dir,
+		Stdout:  &stdout,
+		Stderr:  e.Stderr,
+	}
+	if err := execext.RunCommand(opts); err != nil {
+		return "", &dynamicVarError{cause: err, cmd: opts.Command}
+	}
+
+	result := strings.TrimSuffix(stdout.String(), "\n")
+	if strings.ContainsRune(result, '\n') {
+		return "", ErrMultilineResultCmd
+	}
+
+	result = strings.TrimSpace(result)
+	e.verbosePrintfln(`task: dynamic variable: "%s", result: "%s"`, value, result)
+	e.dynamicCache[value] = result
+	return result, nil
+}