shell

package
v2.6.4+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2019 License: BSD-3-Clause Imports: 7 Imported by: 30

Documentation

Overview

Package shell contains high-level features that use the syntax, expand, and interp packages under the hood.

Please note that this package uses POSIX Shell syntax. As such, path names on Windows need to use double backslashes or be within single quotes when given to functions like Fields. For example:

shell.Fields("echo /foo/bar")     // on Unix-like
shell.Fields("echo C:\\foo\\bar") // on Windows
shell.Fields("echo 'C:\foo\bar'") // on Windows, with quotes

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Expand

func Expand(s string, env func(string) string) (string, error)

Expand performs shell expansion on s as if it were within double quotes, using env to resolve variables. This includes parameter expansion, arithmetic expansion, and quote removal.

If env is nil, the current environment variables are used. Empty variables are treated as unset; to support variables which are set but empty, use the expand package directly.

Command subsitutions like $(echo foo) aren't supported to avoid running arbitrary code. To support those, use an interpreter with the expand package.

An error will be reported if the input string had invalid syntax.

Example
package main

import (
	"fmt"

	"mvdan.cc/sh/shell"
)

func main() {
	env := func(name string) string {
		switch name {
		case "HOME":
			return "/home/user"
		}
		return "" // leave the rest unset
	}
	out, _ := shell.Expand("No place like $HOME", env)
	fmt.Println(out)

	out, _ = shell.Expand("Some vars are ${missing:-awesome}", env)
	fmt.Println(out)

	out, _ = shell.Expand("Math is fun! $((12 * 34))", nil)
	fmt.Println(out)
}
Output:

No place like /home/user
Some vars are awesome
Math is fun! 408

func Fields

func Fields(s string, env func(string) string) ([]string, error)

Fields performs shell expansion on s as if it were a command's arguments, using env to resolve variables. It is similar to Expand, but includes brace expansion, tilde expansion, and globbing.

If env is nil, the current environment variables are used. Empty variables are treated as unset; to support variables which are set but empty, use the expand package directly.

An error will be reported if the input string had invalid syntax.

Example
package main

import (
	"fmt"

	"mvdan.cc/sh/shell"
)

func main() {
	env := func(name string) string {
		switch name {
		case "foo":
			return "bar baz"
		}
		return "" // leave the rest unset
	}
	out, _ := shell.Fields(`"many quoted" ' strings '`, env)
	fmt.Printf("%#v\n", out)

	out, _ = shell.Fields("unquoted $foo", env)
	fmt.Printf("%#v\n", out)

	out, _ = shell.Fields(`quoted "$foo"`, env)
	fmt.Printf("%#v\n", out)
}
Output:

[]string{"many quoted", " strings "}
[]string{"unquoted", "bar", "baz"}
[]string{"quoted", "bar baz"}

func SourceFile

func SourceFile(ctx context.Context, path string) (map[string]expand.Variable, error)

SourceFile sources a shell file from disk and returns the variables declared in it. It is a convenience function that uses a default shell parser, parses a file from disk, and calls SourceNode.

This function should be used with caution, as it can interpret arbitrary code. Untrusted shell programs shoudn't be sourced outside of a sandbox environment.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"

	"mvdan.cc/sh/shell"
)

func main() {
	src := `
		foo=abc
		foo+=012
		if true; then
			bar=$(echo example_*.go)
		fi
	`
	ioutil.WriteFile("f.sh", []byte(src), 0666)
	defer os.Remove("f.sh")
	vars, err := shell.SourceFile(context.TODO(), "f.sh")
	if err != nil {
		return
	}
	fmt.Println(len(vars))
	fmt.Println("foo", vars["foo"])
	fmt.Println("bar", vars["bar"])
}
Output:

2
foo abc012
bar example_test.go

func SourceNode

func SourceNode(ctx context.Context, node syntax.Node) (map[string]expand.Variable, error)

SourceNode sources a shell program from a node and returns the variables declared in it. It accepts the same set of node types that interp/Runner.Run does.

This function should be used with caution, as it can interpret arbitrary code. Untrusted shell programs shoudn't be sourced outside of a sandbox environment.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL