Documentation

Overview

    Package gosh provides facilities for running and managing processes: start them, wait for them to exit, capture their output streams, pipe messages between them, terminate them (e.g. on SIGINT), and so on.

    Gosh is meant to be used in situations where one might otherwise be tempted to write a shell script. (Oh my gosh, no more shell scripts!)

    For usage examples, see shell_test.go and internal/gosh_example/main.go.

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    func BuildGoPkg

    func BuildGoPkg(sh *Shell, binDir, pkg string, flags ...string) string

      BuildGoPkg compiles a Go package using the "go build" command and writes the resulting binary to the given binDir, or to the -o flag location if specified. If -o is relative, it is interpreted as relative to binDir. If the binary already exists at the target location, it is not rebuilt. Returns the absolute path to the binary.

      func InitChildMain

      func InitChildMain()

        InitChildMain must be called early on in main() of child processes. It spawns goroutines to kill the current process when certain conditions are met, per Cmd.IgnoreParentExit and Cmd.ExitAfter.

        func InitMain

        func InitMain()

          InitMain must be called early on in main(), before flags are parsed. In the parent process, it returns immediately with no effect. In a child process for a Shell.FuncCmd command, it runs the specified function, then exits.

          func SendVars

          func SendVars(vars map[string]string)

            SendVars sends the given vars to the parent process. Writes a string of the form "<goshVars{ ... JSON-encoded vars ... }goshVars>\n" to stderr.

            Types

            type Cmd

            type Cmd struct {
            	// Err is the most recent error from this Cmd (may be nil).
            	Err error
            	// Path is the path of the command to run.
            	Path string
            	// Vars is the map of env vars for this Cmd.
            	Vars map[string]string
            	// Args is the list of args for this Cmd, starting with the resolved path.
            	// Note, we set Args[0] to the resolved path (rather than the user-specified
            	// name) so that a command started by Shell can reliably determine the path to
            	// its executable.
            	Args []string
            	// IgnoreParentExit, if true, makes it so the child process does not exit when
            	// its parent exits. Only takes effect if the child process was spawned via
            	// Shell.FuncCmd or explicitly calls InitChildMain.
            	IgnoreParentExit bool
            	// ExitAfter, if non-zero, specifies that the child process should exit after
            	// the given duration has elapsed. Only takes effect if the child process was
            	// spawned via Shell.FuncCmd or explicitly calls InitChildMain.
            	ExitAfter time.Duration
            	// PropagateOutput is inherited from Shell.PropagateChildOutput.
            	PropagateOutput bool
            	// OutputDir is inherited from Shell.ChildOutputDir.
            	OutputDir string
            	// ExitErrorIsOk specifies whether an *exec.ExitError should be reported via
            	// Shell.HandleError.
            	ExitErrorIsOk bool
            	// IgnoreClosedPipeError, if true, causes errors from read/write on a closed
            	// pipe to be indistinguishable from success. These errors often occur in
            	// command pipelines, e.g. "yes | head -1", where "yes" will receive a closed
            	// pipe error when it tries to write on stdout, after "head" has exited. If a
            	// closed pipe error occurs, Cmd.Err will be nil, and no err is reported to
            	// Shell.HandleError.
            	IgnoreClosedPipeError bool
            	// ExtraFiles is used to populate ExtraFiles in the underlying exec.Cmd
            	// object. Does not get cloned.
            	ExtraFiles []*os.File
            	// contains filtered or unexported fields
            }

              Cmd represents a command. Not thread-safe. Public fields should not be modified after calling Start.

              func (*Cmd) AddStderrWriter

              func (c *Cmd) AddStderrWriter(w io.Writer)

                AddStderrWriter configures this Cmd to tee stderr to the given Writer. Must be called before Start. If the same Writer is passed to both AddStdoutWriter and AddStderrWriter, Cmd will ensure that Write is never called concurrently.

                func (*Cmd) AddStdoutWriter

                func (c *Cmd) AddStdoutWriter(w io.Writer)

                  AddStdoutWriter configures this Cmd to tee stdout to the given Writer. Must be called before Start. If the same Writer is passed to both AddStdoutWriter and AddStderrWriter, Cmd will ensure that Write is never called concurrently.

                  func (*Cmd) AwaitVars

                  func (c *Cmd) AwaitVars(keys ...string) map[string]string

                    AwaitVars waits for the child process to send values for the given vars (e.g. using SendVars). Must not be called before Start or after Wait.

                    func (*Cmd) Clone

                    func (c *Cmd) Clone() *Cmd

                      Clone returns a new Cmd with a copy of this Cmd's configuration.

                      func (*Cmd) CombinedOutput

                      func (c *Cmd) CombinedOutput() string

                        CombinedOutput calls Start followed by Wait, then returns the command's combined stdout and stderr.

                        func (*Cmd) Pid

                        func (c *Cmd) Pid() int

                          Pid returns the command's PID, or -1 if the command has not been started.

                          func (*Cmd) Run

                          func (c *Cmd) Run()

                            Run calls Start followed by Wait.

                            func (*Cmd) SetStdinReader

                            func (c *Cmd) SetStdinReader(r io.Reader)

                              SetStdinReader configures this Cmd to read stdin from the given Reader. Must be called before Start. Only one call may be made to StdinPipe or SetStdinReader; subsequent calls will fail.

                              func (*Cmd) Shell

                              func (c *Cmd) Shell() *Shell

                                Shell returns the shell that this Cmd was created from.

                                func (*Cmd) Signal

                                func (c *Cmd) Signal(sig os.Signal)

                                  Signal sends a signal to the underlying process.

                                  func (*Cmd) Start

                                  func (c *Cmd) Start()

                                    Start starts the command.

                                    func (*Cmd) StderrPipe

                                    func (c *Cmd) StderrPipe() io.ReadCloser

                                      StderrPipe returns a ReadCloser backed by an unlimited-size pipe for the command's stderr. The pipe will be closed when the process exits, but may also be closed earlier by the caller, e.g. if all expected output has been received. Must be called before Start. May be called more than once; each call creates a new pipe.

                                      func (*Cmd) StdinPipe

                                      func (c *Cmd) StdinPipe() io.WriteCloser

                                        StdinPipe returns a WriteCloser backed by an unlimited-size pipe for the command's stdin. The pipe will be closed when the process exits, but may also be closed earlier by the caller, e.g. if the command does not exit until its stdin is closed. Must be called before Start. Only one call may be made to StdinPipe or SetStdinReader; subsequent calls will fail.

                                        func (*Cmd) Stdout

                                        func (c *Cmd) Stdout() string

                                          Stdout calls Start followed by Wait, then returns the command's stdout.

                                          func (*Cmd) StdoutPipe

                                          func (c *Cmd) StdoutPipe() io.ReadCloser

                                            StdoutPipe returns a ReadCloser backed by an unlimited-size pipe for the command's stdout. The pipe will be closed when the process exits, but may also be closed earlier by the caller, e.g. if all expected output has been received. Must be called before Start. May be called more than once; each call creates a new pipe.

                                            func (*Cmd) StdoutStderr

                                            func (c *Cmd) StdoutStderr() (string, string)

                                              StdoutStderr calls Start followed by Wait, then returns the command's stdout and stderr.

                                              func (*Cmd) Terminate

                                              func (c *Cmd) Terminate(sig os.Signal)

                                                Terminate sends a signal to the underlying process, then waits for it to exit. Terminate is different from Signal followed by Wait: Terminate succeeds as long as the process exits, whereas Wait fails if the exit code isn't 0.

                                                func (*Cmd) Wait

                                                func (c *Cmd) Wait()

                                                  Wait waits for the command to exit.

                                                  type Func

                                                  type Func struct {
                                                  	// contains filtered or unexported fields
                                                  }

                                                    Func is a registered, callable function.

                                                    func RegisterFunc

                                                    func RegisterFunc(name string, fi interface{}) *Func

                                                      RegisterFunc registers the given function with the given name. 'fi' must be a function that accepts gob-encodable arguments and returns an error or nothing.

                                                      type Pipeline

                                                      type Pipeline struct {
                                                      	// contains filtered or unexported fields
                                                      }

                                                        Pipeline represents a pipeline of commands, where the stdout and/or stderr of one command is connected to the stdin of the next command.

                                                        The failure semantics of a pipeline are determined by the failure semantics of each command; by default the pipeline fails if any command fails, and read/write errors on closed pipes are ignored. This is different from bash, where the default is to only check the status of the last command, unless "set -o pipefail" is enabled to check the status of all commands, causing closed pipe errors to fail the pipeline. Use Cmd.ExitErrorIsOk and Cmd.IgnoreClosedPipeError to fine-tune the failure semantics.

                                                        The implementation of Pipeline only uses exported methods from Shell and Cmd.

                                                        func NewPipeline

                                                        func NewPipeline(c *Cmd, cmds ...*Cmd) *Pipeline

                                                          NewPipeline returns a new Pipeline starting with c. The stdout of each command is connected to the stdin of the next command, via calls to Pipeline.PipeStdout. To construct pipelines involving stderr, call Pipeline.PipeStderr or Pipeline.PipeCombinedOutput directly.

                                                          Each command must have been created from the same Shell. Errors are reported to c.Shell, via Shell.HandleError. Sets Cmd.IgnoreClosedPipeError to true for all commands.

                                                          func (*Pipeline) Clone

                                                          func (p *Pipeline) Clone() *Pipeline

                                                            Clone returns a new Pipeline where p's commands are cloned and connected with the same pipeline structure as in p.

                                                            func (*Pipeline) Cmds

                                                            func (p *Pipeline) Cmds() []*Cmd

                                                              Cmds returns the commands in the pipeline.

                                                              func (*Pipeline) CombinedOutput

                                                              func (p *Pipeline) CombinedOutput() string

                                                                CombinedOutput calls Start followed by Wait, then returns the last command's combined stdout and stderr.

                                                                func (*Pipeline) PipeCombinedOutput

                                                                func (p *Pipeline) PipeCombinedOutput(c *Cmd)

                                                                  PipeCombinedOutput connects the combined stdout and stderr of the last command in p to the stdin of c, and appends c to the commands in p. Must be called before Start. Sets c.IgnoreClosedPipeError to true.

                                                                  func (*Pipeline) PipeStderr

                                                                  func (p *Pipeline) PipeStderr(c *Cmd)

                                                                    PipeStderr connects the stderr of the last command in p to the stdin of c, and appends c to the commands in p. Must be called before Start. Sets c.IgnoreClosedPipeError to true.

                                                                    func (*Pipeline) PipeStdout

                                                                    func (p *Pipeline) PipeStdout(c *Cmd)

                                                                      PipeStdout connects the stdout of the last command in p to the stdin of c, and appends c to the commands in p. Must be called before Start. Sets c.IgnoreClosedPipeError to true.

                                                                      func (*Pipeline) Run

                                                                      func (p *Pipeline) Run()

                                                                        Run calls Start followed by Wait.

                                                                        func (*Pipeline) Signal

                                                                        func (p *Pipeline) Signal(sig os.Signal)

                                                                          Signal sends a signal to all underlying processes in the pipeline.

                                                                          func (*Pipeline) Start

                                                                          func (p *Pipeline) Start()

                                                                            Start starts all commands in the pipeline.

                                                                            func (*Pipeline) Stdout

                                                                            func (p *Pipeline) Stdout() string

                                                                              Stdout calls Start followed by Wait, then returns the last command's stdout.

                                                                              func (*Pipeline) StdoutStderr

                                                                              func (p *Pipeline) StdoutStderr() (string, string)

                                                                                StdoutStderr calls Start followed by Wait, then returns the last command's stdout and stderr.

                                                                                func (*Pipeline) Terminate

                                                                                func (p *Pipeline) Terminate(sig os.Signal)

                                                                                  Terminate sends a signal to all underlying processes in the pipeline, then waits for all processes to exit. Terminate is different from Signal followed by Wait: Terminate succeeds as long as all processes exit, whereas Wait fails if any process's exit code isn't 0.

                                                                                  func (*Pipeline) Wait

                                                                                  func (p *Pipeline) Wait()

                                                                                    Wait waits for all commands in the pipeline to exit.

                                                                                    type Shell

                                                                                    type Shell struct {
                                                                                    	// Err is the most recent error from this Shell or any of its child Cmds (may
                                                                                    	// be nil).
                                                                                    	Err error
                                                                                    	// PropagateChildOutput specifies whether to propagate child stdout and stderr
                                                                                    	// up to the parent's stdout and stderr.
                                                                                    	PropagateChildOutput bool
                                                                                    	// ChildOutputDir, if non-empty, makes it so child stdout and stderr are tee'd
                                                                                    	// to files in the specified directory.
                                                                                    	ChildOutputDir string
                                                                                    	// ContinueOnError specifies whether to invoke TB.FailNow on error, i.e.
                                                                                    	// whether to panic on error. Users that set ContinueOnError to true should
                                                                                    	// inspect sh.Err after each Shell method invocation.
                                                                                    	ContinueOnError bool
                                                                                    	// Vars is the map of env vars for this Shell.
                                                                                    	Vars map[string]string
                                                                                    	// Args is the list of args to append to subsequent command invocations.
                                                                                    	Args []string
                                                                                    	// Set the depth to use for runtime.Caller when generating error messages.
                                                                                    	ErrorDepth int
                                                                                    	// contains filtered or unexported fields
                                                                                    }

                                                                                      Shell represents a shell. Not thread-safe.

                                                                                      func NewShell

                                                                                      func NewShell(tb TB) *Shell

                                                                                        NewShell returns a new Shell. Tests and benchmarks should pass their testing.TB instance; non-tests should pass nil.

                                                                                        func (*Shell) AddCleanupHandler

                                                                                        func (sh *Shell) AddCleanupHandler(f func())

                                                                                          AddCleanupHandler registers the given function to be called during cleanup. Cleanup handlers are called in LIFO order, possibly in a separate goroutine spawned by gosh.

                                                                                          func (*Shell) Cleanup

                                                                                          func (sh *Shell) Cleanup()

                                                                                            Cleanup cleans up all resources (child processes, temporary files and directories) associated with this Shell. It is safe (and recommended) to call Cleanup after a Shell error. It is also safe to call Cleanup multiple times; calls after the first return immediately with no effect. Cleanup never calls HandleError.

                                                                                            func (*Shell) Cmd

                                                                                            func (sh *Shell) Cmd(name string, args ...string) *Cmd

                                                                                              Cmd returns a Cmd for an invocation of the named program. The given arguments are passed to the child as command-line arguments.

                                                                                              func (*Shell) FuncCmd

                                                                                              func (sh *Shell) FuncCmd(f *Func, args ...interface{}) *Cmd

                                                                                                FuncCmd returns a Cmd for an invocation of the given registered Func. The given arguments are gob-encoded in the parent process, then gob-decoded in the child and passed to the Func as parameters. To specify command-line arguments for the child invocation, append to the returned Cmd's Args.

                                                                                                func (*Shell) HandleError

                                                                                                func (sh *Shell) HandleError(err error)

                                                                                                  HandleError sets sh.Err. If err is not nil and sh.ContinueOnError is false, it also calls TB.FailNow.

                                                                                                  func (*Shell) HandleErrorWithSkip

                                                                                                  func (sh *Shell) HandleErrorWithSkip(err error, skip int)

                                                                                                    HandleErrorWithSkip is like HandleError, but allows clients to specify the skip value to pass to runtime.Caller.

                                                                                                    func (*Shell) MakeTempDir

                                                                                                    func (sh *Shell) MakeTempDir() string

                                                                                                      MakeTempDir creates a new temporary directory in os.TempDir and returns the path of the new directory.

                                                                                                      func (*Shell) MakeTempFile

                                                                                                      func (sh *Shell) MakeTempFile() *os.File

                                                                                                        MakeTempFile creates a new temporary file in os.TempDir, opens the file for reading and writing, and returns the resulting *os.File.

                                                                                                        func (*Shell) Move

                                                                                                        func (sh *Shell) Move(oldpath, newpath string)

                                                                                                          Move moves a file from 'oldpath' to 'newpath'. It first attempts os.Rename; if that fails, it copies 'oldpath' to 'newpath', then deletes 'oldpath'. Requires that 'newpath' does not exist, and that the parent directory of 'newpath' does exist. Currently only supports moving an individual file; moving a directory is not yet supported.

                                                                                                          func (*Shell) Ok

                                                                                                          func (sh *Shell) Ok()

                                                                                                            Ok panics iff this Shell is in a state where it's invalid to call other methods. This method is public to facilitate Shell wrapping.

                                                                                                            func (*Shell) Popd

                                                                                                            func (sh *Shell) Popd()

                                                                                                              Popd behaves like Bash popd.

                                                                                                              func (*Shell) Pushd

                                                                                                              func (sh *Shell) Pushd(dir string)

                                                                                                                Pushd behaves like Bash pushd.

                                                                                                                func (*Shell) Wait

                                                                                                                func (sh *Shell) Wait()

                                                                                                                  Wait waits for all commands started by this Shell to exit.

                                                                                                                  type TB

                                                                                                                  type TB interface {
                                                                                                                  	FailNow()
                                                                                                                  	Logf(format string, args ...interface{})
                                                                                                                  }

                                                                                                                    TB is a subset of the testing.TB interface, defined here to avoid depending on the testing package.

                                                                                                                    GOOS=linux, GOARCH=amd64

                                                                                                                    Directories

                                                                                                                    Path Synopsis
                                                                                                                    internal