Documentation ¶
Overview ¶
exex provides a custom Cmd type that wraps exec.Cmd in a way that it will always capture standard error stream if execution fails with an exec.ExitError.
The standard library exec package contains a very useful API to execute commands, however, the exec.Cmd.Run and exec.Cmd.Output methods behave differently in the case of a failed execution. In particular, exec.Cmd.Run will NOT populate exec.ExitError.Stderr in the case of failure, whereas exec.Cmd.Output will do. While this is explicitly noted in the exec package documentation, it is a source of confusion even for experienced users.
Another issue with the standard library package is that if we use exec.Cmd.Output to only capture the error we will be incurring in unnecessary allocations because it uses a bytes.Buffer for capturing STDOUT, and also STDERR will be truncated. The wrappers defined in this library do not have this peformance penalization nor truncate any output.
In order to avoid importing both this package and os/exec, this package provides aliases for the variables and top-level functions os/exec provides.
Index ¶
- Variables
- func Run(cmd string, args ...string) error
- func RunCommand(cmd *exec.Cmd) error
- func RunContext(ctx context.Context, cmd string, args ...string) error
- type Cmd
- func (c *Cmd) CombinedOutput() ([]byte, error)
- func (c *Cmd) Output() ([]byte, error)
- func (c *Cmd) Run() error
- func (c *Cmd) Start() error
- func (c *Cmd) StderrPipe() (io.ReadCloser, error)
- func (c *Cmd) StdinPipe() (io.WriteCloser, error)
- func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
- func (c *Cmd) String() string
- func (c *Cmd) Wait() error
- type Error
- type ExitError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = exec.ErrNotFound
ErrNotFound is an alias for exec.ErrNotFound, the error resulting if a path search failed to find an executable file.
var LookPath = exec.LookPath
LookPath is an alias for exec.LookPath, searches for an executable named file in the directories named by the PATH environment variable. Refer to that package for additional information.
Functions ¶
func Run ¶
Run creates a Cmd and returns the result of executing *Cmd.Run.
Example ¶
package main import ( "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { err := exex.Run("sh", "-c", "foo") var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
func RunCommand ¶
RunCommand wraps an *exec.Cmd into a Cmd and returns the result of calling *Cmd.Run.
Example ¶
package main import ( "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { cmd := exec.Command("sh", "-c", "foo") err := exex.RunCommand(cmd) var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
func RunContext ¶
RunContext creates a Cmd with the given context and returns the result of executing *Cmd.Run.
Example ¶
package main import ( "context" "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { ctx := context.Background() err := exex.RunContext(ctx, "sh", "-c", "foo") var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
Types ¶
type Cmd ¶ added in v0.0.2
Cmd wraps exec.Cmd and represents an external command.
As in the case of exec.Cmd, a Cmd cannot be reused after executed for the first time.
Refer to the exec.Cmd documentation for information on all the functions this type provides except for Run, which is overwritten by this struct.
func Command ¶ added in v0.0.2
Command returns the Cmd struct to execute the named program with the given arguments.
Refer to the exec.Command documentation for additional information.
Example ¶
package main import ( "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { cmd := exex.Command("sh", "-c", "foo") err := cmd.Run() var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
func CommandContext ¶ added in v0.0.2
CommandContext is like Command but the Cmd is associated with a context.
Refer to the exec.Command documentation for additional information.
Example ¶
package main import ( "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { cmd := exex.Command("sh", "-c", "foo") err := cmd.Run() var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
func (*Cmd) CombinedOutput ¶ added in v0.0.4
CombinedOutput runs the command and returns its combined standard output and standard error.
func (*Cmd) Output ¶ added in v0.0.4
Output runs the command and returns its standard output. Any returned error will usually be of type *ExitError. If c.Stderr was nil, Output populates ExitError.Stderr.
func (*Cmd) Run ¶ added in v0.0.2
Run starts the command and waits for it to end.
If the command executes successfully (e.g. exits with a zero status), it returns nil.
If the command fails to execute, the error will be of type *exec.ExitError and it's always guaranteed that its Stderr property will have the contexts of the standard error stream, unless *Cmd.Stderr is specified.
Refer to exec.Cmd.Run documentation for additional information.
Example ¶
package main import ( "errors" "fmt" "os/exec" "github.com/inkel/exex" ) func main() { err := exex.Command("sh", "-c", "foo").Run() var exErr *exec.ExitError if errors.As(err, &exErr) { fmt.Printf("Captured stderr: %q\n", exErr.Stderr) } else { fmt.Printf("Expecting an *exec.ExitError, got %T: %[1]v\n", err) } }
Output:
func (*Cmd) Start ¶ added in v0.0.4
Start starts the specified command but does not wait for it to complete.
func (*Cmd) StderrPipe ¶ added in v0.0.4
func (c *Cmd) StderrPipe() (io.ReadCloser, error)
StderrPipe returns a pipe that will be connected to the command's standard error when the command starts.
func (*Cmd) StdinPipe ¶ added in v0.0.4
func (c *Cmd) StdinPipe() (io.WriteCloser, error)
StdinPipe returns a pipe that will be connected to the command's standard input when the command starts.
func (*Cmd) StdoutPipe ¶ added in v0.0.4
func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
StdoutPipe returns a pipe that will be connected to the command's standard output when the command starts.