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 ¶
- func BuildGoPkg(sh *Shell, binDir, pkg string, flags ...string) string
- func InitChildMain()
- func InitMain()
- func SendVars(vars map[string]string)
- type Cmd
- func (c *Cmd) AddStderrWriter(w io.Writer)
- func (c *Cmd) AddStdoutWriter(w io.Writer)
- func (c *Cmd) AwaitVars(keys ...string) map[string]string
- func (c *Cmd) Clone() *Cmd
- func (c *Cmd) CombinedOutput() string
- func (c *Cmd) Pid() int
- func (c *Cmd) Run()
- func (c *Cmd) SetStdinReader(r io.Reader)
- func (c *Cmd) Shell() *Shell
- func (c *Cmd) Signal(sig os.Signal)
- func (c *Cmd) Start()
- func (c *Cmd) StderrPipe() io.ReadCloser
- func (c *Cmd) StdinPipe() io.WriteCloser
- func (c *Cmd) Stdout() string
- func (c *Cmd) StdoutPipe() io.ReadCloser
- func (c *Cmd) StdoutStderr() (string, string)
- func (c *Cmd) Terminate(sig os.Signal)
- func (c *Cmd) Wait()
- type Func
- type Pipeline
- func (p *Pipeline) Clone() *Pipeline
- func (p *Pipeline) Cmds() []*Cmd
- func (p *Pipeline) CombinedOutput() string
- func (p *Pipeline) PipeCombinedOutput(c *Cmd)
- func (p *Pipeline) PipeStderr(c *Cmd)
- func (p *Pipeline) PipeStdout(c *Cmd)
- func (p *Pipeline) Run()
- func (p *Pipeline) Signal(sig os.Signal)
- func (p *Pipeline) Start()
- func (p *Pipeline) Stdout() string
- func (p *Pipeline) StdoutStderr() (string, string)
- func (p *Pipeline) Terminate(sig os.Signal)
- func (p *Pipeline) Wait()
- type Shell
- func (sh *Shell) AddCleanupHandler(f func())
- func (sh *Shell) Cleanup()
- func (sh *Shell) Cmd(name string, args ...string) *Cmd
- func (sh *Shell) FuncCmd(f *Func, args ...interface{}) *Cmd
- func (sh *Shell) HandleError(err error)
- func (sh *Shell) HandleErrorWithSkip(err error, skip int)
- func (sh *Shell) MakeTempDir() string
- func (sh *Shell) MakeTempFile() *os.File
- func (sh *Shell) Move(oldpath, newpath string)
- func (sh *Shell) Ok()
- func (sh *Shell) Popd()
- func (sh *Shell) Pushd(dir string)
- func (sh *Shell) Wait()
- type TB
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildGoPkg ¶
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.
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 ¶
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 ¶
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 ¶
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) CombinedOutput ¶
CombinedOutput calls Start followed by Wait, then returns the command's combined stdout and stderr.
func (*Cmd) SetStdinReader ¶
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) 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) 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 ¶
StdoutStderr calls Start followed by Wait, then returns the command's stdout and stderr.
type Func ¶
type Func struct {
// contains filtered or unexported fields
}
Func is a registered, callable function.
func RegisterFunc ¶
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 ¶
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 ¶
Clone returns a new Pipeline where p's commands are cloned and connected with the same pipeline structure as in p.
func (*Pipeline) CombinedOutput ¶
CombinedOutput calls Start followed by Wait, then returns the last command's combined stdout and stderr.
func (*Pipeline) PipeCombinedOutput ¶
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 ¶
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 ¶
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) Stdout ¶
Stdout calls Start followed by Wait, then returns the last command's stdout.
func (*Pipeline) StdoutStderr ¶
StdoutStderr calls Start followed by Wait, then returns the last command's stdout and stderr.
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 // contains filtered or unexported fields }
Shell represents a shell. Not thread-safe.
func NewShell ¶
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 ¶
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 ¶
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 ¶
HandleError sets sh.Err. If err is not nil and sh.ContinueOnError is false, it also calls TB.FailNow.
func (*Shell) HandleErrorWithSkip ¶
HandleErrorWithSkip is like HandleError, but allows clients to specify the skip value to pass to runtime.Caller.
func (*Shell) MakeTempDir ¶
MakeTempDir creates a new temporary directory in os.TempDir and returns the path of the new directory.
func (*Shell) MakeTempFile ¶
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 ¶
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.