expand

package
v0.0.0-...-a833481 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2026 License: BSD-3-Clause Imports: 20 Imported by: 0

Documentation

Overview

Package expand contains code to perform various shell expansions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Arithm

func Arithm(cfg *Config, expr syntax.ArithmExpr) (int, error)

func Braces

func Braces(word *syntax.Word) []*syntax.Word

Braces performs brace expansion on a word, given that it contains any syntax.BraceExp parts. For example, the word with a brace expansion "foo{bar,baz}" will return two literal words, "foobar" and "foobaz".

Note that the resulting words may share word parts.

func Document

func Document(cfg *Config, word *syntax.Word) (string, error)

Document expands a single shell word as if it were a here-document body. It is similar to Literal, but without brace expansion, tilde expansion, and globbing.

The config specifies shell expansion options; nil behaves the same as an empty config.

func Fields

func Fields(cfg *Config, words ...*syntax.Word) ([]string, error)

Fields is a pre-iterators API which now wraps FieldsSeq.

func FieldsSeq

func FieldsSeq(cfg *Config, words ...*syntax.Word) iter.Seq2[string, error]

FieldsSeq expands a number of words as if they were arguments in a shell command. This includes brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, and globbing.

func Format

func Format(cfg *Config, format string, args []string) (string, int, error)

Format expands a format string with a number of arguments, following the shell's format specifications. These include printf(1), among others.

The resulting string is returned, along with the number of arguments used. Note that the resulting string may contain null bytes, for example if the format string used `\x00`. The caller should terminate the string at the first null byte if needed, such as when expanding for `$'foo\x00bar'`.

The config specifies shell expansion options; nil behaves the same as an empty config.

func Literal

func Literal(cfg *Config, word *syntax.Word) (string, error)

Literal expands a single shell word. It is similar to Fields, but the result is a single string. This is the behavior when a word is used as the value in a shell variable assignment, for example.

The config specifies shell expansion options; nil behaves the same as an empty config.

func Pattern

func Pattern(cfg *Config, word *syntax.Word) (string, error)

Pattern expands a single shell word as a pattern, using pattern.QuoteMeta on any non-quoted parts of the input word. The result can be used on pattern.Regexp directly.

The config specifies shell expansion options; nil behaves the same as an empty config.

func ReadFields

func ReadFields(cfg *Config, s string, n int, raw bool) []string

ReadFields splits and returns n fields from s, like the "read" shell builtin. If raw is set, backslash escape sequences are not interpreted.

The config specifies shell expansion options; nil behaves the same as an empty config.

Types

type Config

type Config struct {
	// Env is used to get and set environment variables when performing
	// shell expansions. Some special parameters are also expanded via this
	// interface, such as:
	//
	//   * "#", "@", "*", "0"-"9" for the shell's parameters
	//   * "?", "$", "PPID" for the shell's status and process
	//   * "HOME foo" to retrieve user foo's home directory (if unset,
	//     os/user.Lookup will be used)
	//
	// If nil, there are no environment variables set. Use
	// ListEnviron(os.Environ()...) to use the system's environment
	// variables.
	Env Environ

	// CmdSubst expands a command substitution node, writing its standard
	// output to the provided [io.Writer].
	//
	// If nil, encountering a command substitution will result in an
	// UnexpectedCommandError.
	CmdSubst func(io.Writer, *syntax.CmdSubst) error

	// ProcSubst expands a process substitution node.
	ProcSubst func(*syntax.ProcSubst) (string, error)

	// ReadDir is the older form of [ReadDir2], before io/fs.
	//
	// Deprecated: use ReadDir2 instead.
	ReadDir func(string) ([]fs.FileInfo, error)

	// ReadDir2 is used for file path globbing.
	// If nil, and [ReadDir] is nil as well, globbing is disabled.
	// Use [os.ReadDir] to use the filesystem directly.
	ReadDir2 func(string) ([]fs.DirEntry, error)

	// GlobStar corresponds to the shell option which allows globbing with "**".
	GlobStar bool

	// DotGlob corresponds to the shell option which allows filenames beginning
	// with a dot to be matched by a pattern which does not begin with a dot.
	DotGlob bool

	// NoCaseGlob corresponds to the shell option which causes case-insensitive
	// pattern matching in pathname expansion.
	NoCaseGlob bool

	// NullGlob corresponds to the shell option which allows globbing
	// patterns which match nothing to result in zero fields.
	NullGlob bool

	// NoUnset corresponds to the shell option which treats unset variables
	// as errors.
	NoUnset bool

	// ExtGlob corresponds to the shell option which allows using extended
	// pattern matching features when performing pathname expansion (globbing).
	ExtGlob bool
	// contains filtered or unexported fields
}

A Config specifies details about how shell expansion should be performed. The zero value is a valid configuration.

type Environ

type Environ interface {
	// Get retrieves a variable by its name. To check if the variable is
	// set, use Variable.IsSet.
	Get(name string) Variable

	// Each iterates over all the currently set variables, calling the
	// supplied function on each variable. Iteration is stopped if the
	// function returns false.
	//
	// The names used in the calls aren't required to be unique or sorted.
	// If a variable name appears twice, the latest occurrence takes
	// priority.
	//
	// Each is required to forward exported variables when executing
	// programs.
	Each(func(name string, vr Variable) bool)
}

Environ is the base interface for a shell's environment, allowing it to fetch variables by name and to iterate over all the currently set variables.

func FuncEnviron

func FuncEnviron(fn func(string) string) Environ

FuncEnviron wraps a function mapping variable names to their string values, and implements Environ. Empty strings returned by the function will be treated as unset variables. All variables will be exported.

Note that the returned Environ's Each method will be a no-op.

func ListEnviron

func ListEnviron(pairs ...string) Environ

ListEnviron returns an Environ with the supplied variables, in the form "key=value". All variables will be exported. The last value in pairs is used if multiple values are present.

On Windows, where environment variable names are case-insensitive, the resulting variable names will all be uppercase.

type UnexpectedCommandError

type UnexpectedCommandError struct {
	Node *syntax.CmdSubst
}

UnexpectedCommandError is returned if a command substitution is encountered when [Config.CmdSubst] is nil.

func (UnexpectedCommandError) Error

func (u UnexpectedCommandError) Error() string

type UnsetParameterError

type UnsetParameterError struct {
	Node    *syntax.ParamExp
	Message string
}

UnsetParameterError is returned when a parameter expansion encounters an unset variable and [Config.NoUnset] has been set.

func (UnsetParameterError) Error

func (u UnsetParameterError) Error() string

type ValueKind

type ValueKind uint8

ValueKind describes which kind of value the variable holds. While most unset variables will have an Unknown kind, an unset variable may have a kind associated too, such as via `declare -a foo` resulting in Indexed.

const (
	// Unknown is used for unset variables which do not have a kind yet.
	Unknown ValueKind = iota
	// String describes plain string variables, such as `foo=bar`.
	String
	// NameRef describes variables which reference another by name, such as `declare -n foo=foo2`.
	NameRef
	// Indexed describes indexed array variables, such as `foo=(bar baz)`.
	Indexed
	// Associative describes associative array variables, such as `foo=([bar]=x [baz]=y)`.
	Associative

	// KeepValue is used by [WriteEnviron.Set] to signal that we are changing attributes
	// about a variable, such as exporting it, without changing its value at all.
	KeepValue

	// Deprecated: use [Unknown], as tracking whether or not a variable is set
	// is now done via [Variable.Set].
	// Otherwise it was impossible to describe an unset variable with a known kind
	// such as `declare -A foo`.
	Unset = Unknown
)

func (ValueKind) String

func (i ValueKind) String() string

type Variable

type Variable struct {
	// Set is true when the variable has been set to a value,
	// which may be empty.
	Set bool

	Local    bool
	Exported bool
	ReadOnly bool

	// Kind defines which of the value fields below should be used.
	Kind ValueKind

	Str  string            // Used when Kind is String or NameRef.
	List []string          // Used when Kind is Indexed.
	Map  map[string]string // Used when Kind is Associative.
}

Variable describes a shell variable, which can have a number of attributes and a value.

func (Variable) Declared

func (v Variable) Declared() bool

Declared reports whether the variable has been declared. Declared variables may not be set; `export foo` is exported but not set to a value, and `declare -a foo` is an indexed array but not set to a value.

func (Variable) Flags

func (v Variable) Flags() string

Flags returns the variable's attribute flags in the order used by bash's declare builtin and ${var@a}: type (a/A/n), readonly (r), exported (x).

func (Variable) IsSet

func (v Variable) IsSet() bool

IsSet reports whether the variable has been set to a value. The zero value of a Variable is unset.

func (Variable) Resolve

func (v Variable) Resolve(env Environ) (string, Variable)

Resolve follows a number of nameref variables, returning the last reference name that was followed and the variable that it points to.

func (Variable) String

func (v Variable) String() string

String returns the variable's value as a string. In general, this only makes sense if the variable has a string value or no value at all.

type WriteEnviron

type WriteEnviron interface {
	Environ
	// Set sets a variable by name. If !vr.IsSet(), the variable is being
	// unset; otherwise, the variable is being replaced.
	//
	// The given variable can have the kind [KeepValue] to replace an existing
	// variable's attributes without changing its value at all.
	// This is helpful to implement `readonly foo=bar; export foo`,
	// as the second declaration needs to clearly signal that the value is not modified.
	//
	// An error may be returned if the operation is invalid, such as if the
	// name is empty or if we're trying to overwrite a read-only variable.
	Set(name string, vr Variable) error
}

WriteEnviron is an extension on Environ that supports modifying and deleting variables.

Jump to

Keyboard shortcuts

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