execx

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2026 License: MIT Imports: 19 Imported by: 0

README

str logo

execx is an ergonomic, fluent wrapper around Go’s `os/exec` package.

Go Reference Go Test Go version Latest tag Tests Go Report Card

What execx is

execx is a small, explicit wrapper around os/exec. It keeps the exec.Cmd model but adds fluent construction and consistent result handling.

There is no shell interpolation. Arguments, environment, and I/O are set directly, and nothing runs until you call Run, Output, or Start.

Installation

go get github.com/goforj/execx

Quick Start

out, _ := execx.Command("echo", "hello").OutputTrimmed()
fmt.Println(out)
// #string hello

On Windows, use cmd /c echo hello or powershell -Command "echo hello" for shell built-ins.

Basic usage

Build a command and run it:

cmd := execx.Command("echo").Arg("hello")
res, _ := cmd.Run()
fmt.Print(res.Stdout)
// hello

Arguments are appended deterministically and never shell-expanded.

Output handling

Use Output variants when you only need stdout:

out, _ := execx.Command("echo", "hello").OutputTrimmed()
fmt.Println(out)
// #string hello

Output, OutputBytes, OutputTrimmed, and CombinedOutput differ only in how they return data.

Pipelining

Pipelines run on all platforms; command availability is OS-specific.

out, _ := execx.Command("printf", "go").
	Pipe("tr", "a-z", "A-Z").
	OutputTrimmed()
fmt.Println(out)
// #string GO

On Windows, use cmd /c or powershell -Command for shell built-ins.

PipeStrict (default) stops at the first failing stage and returns that error.
PipeBestEffort runs all stages, returns the last stage output, and surfaces the first error if any stage failed.

Context & cancellation

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, _ := execx.Command("go", "env", "GOOS").WithContext(ctx).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

Environment & I/O control

Environment is explicit and deterministic:

cmd := execx.Command("echo", "hello").Env("MODE=prod")
fmt.Println(strings.Contains(strings.Join(cmd.EnvList(), ","), "MODE=prod"))
// #bool true

Standard input is opt-in:

out, _ := execx.Command("cat").
	StdinString("hi").
	OutputTrimmed()
fmt.Println(out)
// #string hi

Advanced features

For process control, use Start with the Process helpers:

proc := execx.Command("go", "env", "GOOS").Start()
res, _ := proc.Wait()
fmt.Println(res.ExitCode == 0)
// #bool true

Signals, timeouts, and OS controls are documented in the API section below.

ShadowPrint is available for emitting the command line before and after execution.

Kitchen Sink Chaining Example

// Run executes the command and returns the result and any error.

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

res, err := execx.
    Command("printf", "hello\nworld\n").
    Pipe("tr", "a-z", "A-Z").
    Env("MODE=demo").
    WithContext(ctx).
    OnStdout(func(line string) {
        fmt.Println("OUT:", line)
    }).
    OnStderr(func(line string) {
        fmt.Println("ERR:", line)
    }).
    Run()

    if !res.OK() {
        log.Fatalf("command failed: %v", err)
    }

    fmt.Printf("Stdout: %q\n", res.Stdout)
    fmt.Printf("Stderr: %q\n", res.Stderr)
    fmt.Printf("ExitCode: %d\n", res.ExitCode)
    fmt.Printf("Error: %v\n", res.Err)
    fmt.Printf("Duration: %v\n", res.Duration)
    // OUT: HELLO
    // OUT: WORLD
    // Stdout: "HELLO\nWORLD\n"
    // Stderr: ""
    // ExitCode: 0
    // Error: <nil>
    // Duration: 10.123456ms

Error handling model

execx returns two error surfaces:

  1. err (from Run, Output, CombinedOutput, Wait, etc) only reports execution failures:

    • start failures (binary not found, not executable, OS start error)
    • context cancellations or timeouts (WithContext, WithTimeout, WithDeadline)
    • pipeline failures based on PipeStrict / PipeBestEffort
  2. Result.Err mirrors err for convenience; it is not for exit status.

Exit status is always reported via Result.ExitCode, even on non-zero exits. A non-zero exit does not automatically produce err.

Use err when you want to handle execution failures, and check Result.ExitCode (or Result.OK() / Result.IsExitCode) when you care about command success.

Non-goals and design principles

Design principles:

  • Explicit over implicit
  • No shell interpolation
  • Composable, deterministic behavior

Non-goals:

  • Shell scripting replacement
  • Command parsing or glob expansion
  • Task runners or build systems
  • Automatic retries or heuristics

All public APIs are covered by runnable examples under ./examples, and the test suite executes them to keep docs and behavior in sync.

API Index

Group Functions
Arguments Arg
Construction Command
Context WithContext WithDeadline WithTimeout
Debugging Args ShellEscaped String
Decoding Decode DecodeJSON DecodeWith DecodeYAML FromCombined FromStderr FromStdout Into Trim
Environment Env EnvAppend EnvInherit EnvList EnvOnly
Errors Error Unwrap
Execution CombinedOutput Output OutputBytes OutputTrimmed Run Start OnExecCmd
Input StdinBytes StdinFile StdinReader StdinString
OS Controls CreationFlags HideWindow Pdeathsig Setpgid Setsid
Pipelining Pipe PipeBestEffort PipeStrict PipelineResults
Process GracefulShutdown Interrupt KillAfter Send Terminate Wait
Results IsExitCode IsSignal OK
Shadow Print ShadowOff ShadowOn ShadowPrint WithFormatter WithMask WithPrefix
Streaming OnStderr OnStdout StderrWriter StdoutWriter WithPTY
WorkingDir Dir

Arguments

Arg

Arg appends arguments to the command.

cmd := execx.Command("printf").Arg("hello")
out, _ := cmd.Output()
fmt.Print(out)
// hello

Construction

Command

Command constructs a new command without executing it.

cmd := execx.Command("printf", "hello")
out, _ := cmd.Output()
fmt.Print(out)
// hello

Context

WithContext

WithContext binds the command to a context.

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, _ := execx.Command("go", "env", "GOOS").WithContext(ctx).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

WithDeadline

WithDeadline binds the command to a deadline.

res, _ := execx.Command("go", "env", "GOOS").WithDeadline(time.Now().Add(2 * time.Second)).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

WithTimeout

WithTimeout binds the command to a timeout.

res, _ := execx.Command("go", "env", "GOOS").WithTimeout(2 * time.Second).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

Debugging

Args

Args returns the argv slice used for execution.

cmd := execx.Command("go", "env", "GOOS")
fmt.Println(strings.Join(cmd.Args(), " "))
// #string go env GOOS

ShellEscaped

ShellEscaped returns a shell-escaped string for logging only.

cmd := execx.Command("echo", "hello world", "it's")
fmt.Println(cmd.ShellEscaped())
// #string echo 'hello world' "it's"

String

String returns a human-readable representation of the command.

cmd := execx.Command("echo", "hello world", "it's")
fmt.Println(cmd.String())
// #string echo "hello world" it's

Decoding

Decode

Decode configures a custom decoder for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source.

type payload struct {
	Name string
}
decoder := execx.DecoderFunc(func(data []byte, dst any) error {
	out, ok := dst.(*payload)
	if !ok {
		return fmt.Errorf("expected *payload")
	}
	_, val, ok := strings.Cut(string(data), "=")
	if !ok {
		return fmt.Errorf("invalid payload")
	}
	out.Name = val
	return nil
})
var out payload
_ = execx.Command("printf", "name=gopher").
	Decode(decoder).
	Into(&out)
fmt.Println(out.Name)
// #string gopher

DecodeJSON

DecodeJSON configures JSON decoding for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

DecodeWith

DecodeWith executes the command and decodes stdout into dst.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeWith(&out, execx.DecoderFunc(json.Unmarshal))
fmt.Println(out.Name)
// #string gopher

DecodeYAML

DecodeYAML configures YAML decoding for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source.

type payload struct {
	Name string `yaml:"name"`
}
var out payload
_ = execx.Command("printf", "name: gopher").
	DecodeYAML().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

FromCombined

FromCombined decodes from combined stdout+stderr.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("sh", "-c", `printf '{"name":"gopher"}'`).
	DecodeJSON().
	FromCombined().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

FromStderr

FromStderr decodes from stderr.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("sh", "-c", `printf '{"name":"gopher"}' 1>&2`).
	DecodeJSON().
	FromStderr().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

FromStdout

FromStdout decodes from stdout (default).

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	FromStdout().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

Into

Into executes the command and decodes into dst.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

Trim

Trim trims whitespace before decoding.

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", "  {\"name\":\"gopher\"}  ").
	DecodeJSON().
	Trim().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

Environment

Env

Env adds environment variables to the command.

cmd := execx.Command("go", "env", "GOOS").Env("MODE=prod")
fmt.Println(strings.Contains(strings.Join(cmd.EnvList(), ","), "MODE=prod"))
// #bool true

EnvAppend

EnvAppend merges variables into the inherited environment.

cmd := execx.Command("go", "env", "GOOS").EnvAppend(map[string]string{"A": "1"})
fmt.Println(strings.Contains(strings.Join(cmd.EnvList(), ","), "A=1"))
// #bool true

EnvInherit

EnvInherit restores default environment inheritance.

cmd := execx.Command("go", "env", "GOOS").EnvInherit()
fmt.Println(len(cmd.EnvList()) > 0)
// #bool true

EnvList

EnvList returns the environment list for execution.

cmd := execx.Command("go", "env", "GOOS").EnvOnly(map[string]string{"A": "1"})
fmt.Println(strings.Join(cmd.EnvList(), ","))
// #string A=1

EnvOnly

EnvOnly ignores the parent environment.

cmd := execx.Command("go", "env", "GOOS").EnvOnly(map[string]string{"A": "1"})
fmt.Println(strings.Join(cmd.EnvList(), ","))
// #string A=1

Errors

Error

Error returns the wrapped error message when available.

err := execx.ErrExec{Err: fmt.Errorf("boom")}
fmt.Println(err.Error())
// #string boom

Unwrap

Unwrap exposes the underlying error.

err := execx.ErrExec{Err: fmt.Errorf("boom")}
fmt.Println(err.Unwrap() != nil)
// #bool true

Execution

CombinedOutput

CombinedOutput executes the command and returns stdout+stderr and any error.

out, err := execx.Command("go", "env", "-badflag").CombinedOutput()
fmt.Print(out)
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

Output

Output executes the command and returns stdout and any error.

out, _ := execx.Command("printf", "hello").Output()
fmt.Print(out)
// hello

OutputBytes

OutputBytes executes the command and returns stdout bytes and any error.

out, _ := execx.Command("printf", "hello").OutputBytes()
fmt.Println(string(out))
// #string hello

OutputTrimmed

OutputTrimmed executes the command and returns trimmed stdout and any error.

out, _ := execx.Command("printf", "hello\n").OutputTrimmed()
fmt.Println(out)
// #string hello

Run

Run executes the command and returns the result and any error.

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.ExitCode == 0)
// #bool true

Start

Start executes the command asynchronously.

proc := execx.Command("go", "env", "GOOS").Start()
res, _ := proc.Wait()
fmt.Println(res.ExitCode == 0)
// #bool true

OnExecCmd

OnExecCmd registers a callback to mutate the underlying exec.Cmd before start.

_, _ = execx.Command("printf", "hi").
	OnExecCmd(func(cmd *exec.Cmd) {
		cmd.Env = append(cmd.Env, "EXAMPLE=1")
	}).
	Run()

Input

StdinBytes

StdinBytes sets stdin from bytes.

out, _ := execx.Command("cat").
	StdinBytes([]byte("hi")).
	Output()
fmt.Println(out)
// #string hi

StdinFile

StdinFile sets stdin from a file.

file, _ := os.CreateTemp("", "execx-stdin")
_, _ = file.WriteString("hi")
_, _ = file.Seek(0, 0)
out, _ := execx.Command("cat").
	StdinFile(file).
	Output()
fmt.Println(out)
// #string hi

StdinReader

StdinReader sets stdin from an io.Reader.

out, _ := execx.Command("cat").
	StdinReader(strings.NewReader("hi")).
	Output()
fmt.Println(out)
// #string hi

StdinString

StdinString sets stdin from a string.

out, _ := execx.Command("cat").
	StdinString("hi").
	Output()
fmt.Println(out)
// #string hi

OS Controls

CreationFlags

CreationFlags is a no-op on non-Windows platforms; on Windows it sets process creation flags.

out, _ := execx.Command("printf", "ok").CreationFlags(execx.CreateNewProcessGroup).Output()
fmt.Print(out)
// ok

HideWindow

HideWindow is a no-op on non-Windows platforms; on Windows it hides console windows.

out, _ := execx.Command("printf", "ok").HideWindow(true).Output()
fmt.Print(out)
// ok

Pdeathsig

Pdeathsig is a no-op on non-Linux platforms; on Linux it signals the child when the parent exits.

out, _ := execx.Command("printf", "ok").Pdeathsig(syscall.SIGTERM).Output()
fmt.Print(out)
// ok

Setpgid

Setpgid places the child in a new process group for group signals.

out, _ := execx.Command("printf", "ok").Setpgid(true).Output()
fmt.Print(out)
// ok

Setsid

Setsid starts the child in a new session, detaching it from the terminal.

out, _ := execx.Command("printf", "ok").Setsid(true).Output()
fmt.Print(out)
// ok

Pipelining

Pipe

Pipe appends a new command to the pipeline. Pipelines run on all platforms.

out, _ := execx.Command("printf", "go").
	Pipe("tr", "a-z", "A-Z").
	OutputTrimmed()
fmt.Println(out)
// #string GO

PipeBestEffort

PipeBestEffort sets best-effort pipeline semantics (run all stages, surface the first error).

res, _ := execx.Command("false").
	Pipe("printf", "ok").
	PipeBestEffort().
	Run()
fmt.Print(res.Stdout)
// ok

PipeStrict

PipeStrict sets strict pipeline semantics (stop on first failure).

res, _ := execx.Command("false").
	Pipe("printf", "ok").
	PipeStrict().
	Run()
fmt.Println(res.ExitCode != 0)
// #bool true

PipelineResults

PipelineResults executes the command and returns per-stage results and any error.

results, _ := execx.Command("printf", "go").
	Pipe("tr", "a-z", "A-Z").
	PipelineResults()
fmt.Printf("%+v", results)
// [
//	{Stdout:go Stderr: ExitCode:0 Err:<nil> Duration:6.367208ms signal:<nil>}
//	{Stdout:GO Stderr: ExitCode:0 Err:<nil> Duration:4.976291ms signal:<nil>}
// ]

Process

GracefulShutdown

GracefulShutdown sends a signal and escalates to kill after the timeout.

proc := execx.Command("sleep", "2").Start()
_ = proc.GracefulShutdown(os.Interrupt, 100*time.Millisecond)
res, _ := proc.Wait()
fmt.Println(res.IsSignal(os.Interrupt))
// #bool true

Interrupt

Interrupt sends an interrupt signal to the process.

proc := execx.Command("sleep", "2").Start()
_ = proc.Interrupt()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:75.987ms signal:interrupt}

KillAfter

KillAfter terminates the process after the given duration.

proc := execx.Command("sleep", "2").Start()
proc.KillAfter(100 * time.Millisecond)
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:100.456ms signal:killed}

Send

Send sends a signal to the process.

proc := execx.Command("sleep", "2").Start()
_ = proc.Send(os.Interrupt)
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:80.123ms signal:interrupt}

Terminate

Terminate kills the process immediately.

proc := execx.Command("sleep", "2").Start()
_ = proc.Terminate()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:70.654ms signal:killed}

Wait

Wait waits for the command to complete and returns the result and any error.

proc := execx.Command("go", "env", "GOOS").Start()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout:darwin
// Stderr: ExitCode:0 Err:<nil> Duration:1.234ms signal:<nil>}

Results

IsExitCode

IsExitCode reports whether the exit code matches.

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.IsExitCode(0))
// #bool true

IsSignal

IsSignal reports whether the command terminated due to a signal.

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.IsSignal(os.Interrupt))
// false

OK

OK reports whether the command exited cleanly without errors.

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.OK())
// #bool true

Shadow Print

ShadowOff

ShadowOff disables shadow printing for this command chain, preserving configuration.

_, _ = execx.Command("printf", "hi").ShadowPrint().ShadowOff().Run()

ShadowOn

ShadowOn enables shadow printing using the previously configured options.

cmd := execx.Command("printf", "hi").
	ShadowPrint(execx.WithPrefix("run"))
cmd.ShadowOff()
_, _ = cmd.ShadowOn().Run()
// run > printf hi
// run > printf hi (1ms)

ShadowPrint

ShadowPrint configures shadow printing for this command chain.

Example: shadow print

_, _ = execx.Command("bash", "-c", `echo "hello world"`).
	ShadowPrint().
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// execx > bash -c 'echo "hello world"'
//
// hello world
//
// execx > bash -c 'echo "hello world"' (1ms)

Example: shadow print options

mask := func(cmd string) string {
	return strings.ReplaceAll(cmd, "token", "***")
}
formatter := func(ev execx.ShadowEvent) string {
	return fmt.Sprintf("shadow: %s %s", ev.Phase, ev.Command)
}
_, _ = execx.Command("bash", "-c", `echo "hello world"`).
	ShadowPrint(
		execx.WithPrefix("execx"),
		execx.WithMask(mask),
		execx.WithFormatter(formatter),
	).
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// shadow: before bash -c 'echo "hello world"'
// hello world
// shadow: after bash -c 'echo "hello world"'

WithFormatter

WithFormatter sets a formatter for ShadowPrint output.

formatter := func(ev execx.ShadowEvent) string {
	return fmt.Sprintf("shadow: %s %s", ev.Phase, ev.Command)
}
_, _ = execx.Command("printf", "hi").ShadowPrint(execx.WithFormatter(formatter)).Run()
// shadow: before printf hi
// shadow: after printf hi

WithMask

WithMask applies a masker to the shadow-printed command string.

mask := func(cmd string) string {
	return strings.ReplaceAll(cmd, "secret", "***")
}
_, _ = execx.Command("printf", "secret").ShadowPrint(execx.WithMask(mask)).Run()
// execx > printf ***
// execx > printf *** (1ms)

WithPrefix

WithPrefix sets the shadow print prefix.

_, _ = execx.Command("printf", "hi").ShadowPrint(execx.WithPrefix("run")).Run()
// run > printf hi
// run > printf hi (1ms)

Streaming

OnStderr

OnStderr registers a line callback for stderr.

_, err := execx.Command("go", "env", "-badflag").
	OnStderr(func(line string) {
		fmt.Println(line)
	}).
	Run()
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

OnStdout

OnStdout registers a line callback for stdout.

_, _ = execx.Command("printf", "hi\n").
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// hi

StderrWriter

StderrWriter sets a raw writer for stderr.

When the writer is a terminal and no line callbacks or combined output are enabled, execx passes stderr through directly and does not buffer it for results.

var out strings.Builder
_, err := execx.Command("go", "env", "-badflag").
	StderrWriter(&out).
	Run()
fmt.Print(out.String())
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

StdoutWriter

StdoutWriter sets a raw writer for stdout.

When the writer is a terminal and no line callbacks or combined output are enabled, execx passes stdout through directly and does not buffer it for results.

var out strings.Builder
_, _ = execx.Command("printf", "hello").
	StdoutWriter(&out).
	Run()
fmt.Print(out.String())
// hello

WithPTY

WithPTY attaches stdout/stderr to a pseudo-terminal.

Output is combined; OnStdout and OnStderr receive the same lines, and Result.Stderr remains empty. Platforms without PTY support return an error when the command runs.

_, _ = execx.Command("printf", "hi").
	WithPTY().
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// hi

WorkingDir

Dir

Dir sets the working directory.

dir := os.TempDir()
out, _ := execx.Command("pwd").
	Dir(dir).
	OutputTrimmed()
fmt.Println(out == dir)
// #bool true

Documentation

Index

Constants

View Source
const (
	// CreateNewProcessGroup starts the process in a new process group.
	CreateNewProcessGroup = 0x00000200
	// CreateNewConsole creates a new console for the process.
	CreateNewConsole = 0x00000010
	// CreateNoWindow prevents console windows from being created.
	CreateNoWindow = 0x08000000
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Cmd

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

Cmd represents a single command invocation or a pipeline stage.

func Command

func Command(name string, args ...string) *Cmd

Command constructs a new command without executing it. @group Construction

Example: command

cmd := execx.Command("printf", "hello")
out, _ := cmd.Output()
fmt.Print(out)
// hello

func (*Cmd) Arg

func (c *Cmd) Arg(values ...any) *Cmd

Arg appends arguments to the command. @group Arguments

Example: add args

cmd := execx.Command("printf").Arg("hello")
out, _ := cmd.Output()
fmt.Print(out)
// hello

func (*Cmd) Args

func (c *Cmd) Args() []string

Args returns the argv slice used for execution. @group Debugging

Example: args

cmd := execx.Command("go", "env", "GOOS")
fmt.Println(strings.Join(cmd.Args(), " "))
// #string go env GOOS

func (*Cmd) CombinedOutput

func (c *Cmd) CombinedOutput() (string, error)

CombinedOutput executes the command and returns stdout+stderr and any error. @group Execution

Example: combined output

out, err := execx.Command("go", "env", "-badflag").CombinedOutput()
fmt.Print(out)
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

func (*Cmd) CreationFlags

func (c *Cmd) CreationFlags(_ uint32) *Cmd

CreationFlags is a no-op on non-Windows platforms; on Windows it sets process creation flags. @group OS Controls

func (*Cmd) Decode added in v0.1.0

func (c *Cmd) Decode(decoder Decoder) *DecodeChain

Decode configures a custom decoder for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source. @group Decoding

Example: decode custom

type payload struct {
	Name string
}
decoder := execx.DecoderFunc(func(data []byte, dst any) error {
	out, ok := dst.(*payload)
	if !ok {
		return fmt.Errorf("expected *payload")
	}
	_, val, ok := strings.Cut(string(data), "=")
	if !ok {
		return fmt.Errorf("invalid payload")
	}
	out.Name = val
	return nil
})
var out payload
_ = execx.Command("printf", "name=gopher").
	Decode(decoder).
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*Cmd) DecodeJSON added in v0.1.0

func (c *Cmd) DecodeJSON() *DecodeChain

DecodeJSON configures JSON decoding for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source. @group Decoding

Example: decode json

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*Cmd) DecodeWith added in v0.1.0

func (c *Cmd) DecodeWith(dst any, decoder Decoder) error

DecodeWith executes the command and decodes stdout into dst. @group Decoding

Example: decode with

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeWith(&out, execx.DecoderFunc(json.Unmarshal))
fmt.Println(out.Name)
// #string gopher

func (*Cmd) DecodeYAML added in v0.1.0

func (c *Cmd) DecodeYAML() *DecodeChain

DecodeYAML configures YAML decoding for this command. Decoding reads from stdout by default; use FromStdout, FromStderr, or FromCombined to select a source. @group Decoding

Example: decode yaml

type payload struct {
	Name string `yaml:"name"`
}
var out payload
_ = execx.Command("printf", "name: gopher").
	DecodeYAML().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*Cmd) Dir

func (c *Cmd) Dir(path string) *Cmd

Dir sets the working directory. @group WorkingDir

Example: change dir

dir := os.TempDir()
out, _ := execx.Command("pwd").
	Dir(dir).
	OutputTrimmed()
fmt.Println(out == dir)
// #bool true

func (*Cmd) Env

func (c *Cmd) Env(values ...any) *Cmd

Env adds environment variables to the command. @group Environment

Example: set env

cmd := execx.Command("go", "env", "GOOS").Env("MODE=prod")
fmt.Println(strings.Contains(strings.Join(cmd.EnvList(), ","), "MODE=prod"))
// #bool true

func (*Cmd) EnvAppend

func (c *Cmd) EnvAppend(values map[string]string) *Cmd

EnvAppend merges variables into the inherited environment. @group Environment

Example: append env

cmd := execx.Command("go", "env", "GOOS").EnvAppend(map[string]string{"A": "1"})
fmt.Println(strings.Contains(strings.Join(cmd.EnvList(), ","), "A=1"))
// #bool true

func (*Cmd) EnvInherit

func (c *Cmd) EnvInherit() *Cmd

EnvInherit restores default environment inheritance. @group Environment

Example: inherit env

cmd := execx.Command("go", "env", "GOOS").EnvInherit()
fmt.Println(len(cmd.EnvList()) > 0)
// #bool true

func (*Cmd) EnvList

func (c *Cmd) EnvList() []string

EnvList returns the environment list for execution. @group Environment

Example: env list

cmd := execx.Command("go", "env", "GOOS").EnvOnly(map[string]string{"A": "1"})
fmt.Println(strings.Join(cmd.EnvList(), ","))
// #string A=1

func (*Cmd) EnvOnly

func (c *Cmd) EnvOnly(values map[string]string) *Cmd

EnvOnly ignores the parent environment. @group Environment

Example: replace env

cmd := execx.Command("go", "env", "GOOS").EnvOnly(map[string]string{"A": "1"})
fmt.Println(strings.Join(cmd.EnvList(), ","))
// #string A=1

func (*Cmd) HideWindow

func (c *Cmd) HideWindow(_ bool) *Cmd

HideWindow is a no-op on non-Windows platforms; on Windows it hides console windows. @group OS Controls

func (*Cmd) OnExecCmd added in v1.0.1

func (c *Cmd) OnExecCmd(fn func(*exec.Cmd)) *Cmd

OnExecCmd registers a callback to mutate the underlying exec.Cmd before start. @group Execution

Example: exec cmd

_, _ = execx.Command("printf", "hi").
	OnExecCmd(func(cmd *exec.Cmd) {
		cmd.SysProcAttr = &syscall.SysProcAttr{}
	}).
	Run()

func (*Cmd) OnStderr

func (c *Cmd) OnStderr(fn func(string)) *Cmd

OnStderr registers a line callback for stderr. @group Streaming

Example: stderr lines

_, err := execx.Command("go", "env", "-badflag").
	OnStderr(func(line string) {
		fmt.Println(line)
	}).
	Run()
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

func (*Cmd) OnStdout

func (c *Cmd) OnStdout(fn func(string)) *Cmd

OnStdout registers a line callback for stdout. @group Streaming

Example: stdout lines

_, _ = execx.Command("printf", "hi\n").
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// hi

func (*Cmd) Output

func (c *Cmd) Output() (string, error)

Output executes the command and returns stdout and any error. @group Execution

Example: output

out, _ := execx.Command("printf", "hello").Output()
fmt.Print(out)
// hello

func (*Cmd) OutputBytes

func (c *Cmd) OutputBytes() ([]byte, error)

OutputBytes executes the command and returns stdout bytes and any error. @group Execution

Example: output bytes

out, _ := execx.Command("printf", "hello").OutputBytes()
fmt.Println(string(out))
// #string hello

func (*Cmd) OutputTrimmed

func (c *Cmd) OutputTrimmed() (string, error)

OutputTrimmed executes the command and returns trimmed stdout and any error. @group Execution

Example: output trimmed

out, _ := execx.Command("printf", "hello\n").OutputTrimmed()
fmt.Println(out)
// #string hello

func (*Cmd) Pdeathsig

func (c *Cmd) Pdeathsig(sig syscall.Signal) *Cmd

Pdeathsig is a no-op on non-Linux platforms; on Linux it signals the child when the parent exits. @group OS Controls

Example: pdeathsig

out, _ := execx.Command("printf", "ok").Pdeathsig(syscall.SIGTERM).Output()
fmt.Print(out)
// ok

func (*Cmd) Pipe

func (c *Cmd) Pipe(name string, args ...string) *Cmd

Pipe appends a new command to the pipeline. Pipelines run on all platforms. @group Pipelining

Example: pipe

out, _ := execx.Command("printf", "go").
	Pipe("tr", "a-z", "A-Z").
	OutputTrimmed()
fmt.Println(out)
// #string GO

func (*Cmd) PipeBestEffort

func (c *Cmd) PipeBestEffort() *Cmd

PipeBestEffort sets best-effort pipeline semantics (run all stages, surface the first error). @group Pipelining

Example: best effort

res, _ := execx.Command("false").
	Pipe("printf", "ok").
	PipeBestEffort().
	Run()
fmt.Print(res.Stdout)
// ok

func (*Cmd) PipeStrict

func (c *Cmd) PipeStrict() *Cmd

PipeStrict sets strict pipeline semantics (stop on first failure). @group Pipelining

Example: strict

res, _ := execx.Command("false").
	Pipe("printf", "ok").
	PipeStrict().
	Run()
fmt.Println(res.ExitCode != 0)
// #bool true

func (*Cmd) PipelineResults

func (c *Cmd) PipelineResults() ([]Result, error)

PipelineResults executes the command and returns per-stage results and any error. @group Pipelining

Example: pipeline results

results, _ := execx.Command("printf", "go").
	Pipe("tr", "a-z", "A-Z").
	PipelineResults()
fmt.Printf("%+v", results)
// [
//	{Stdout:go Stderr: ExitCode:0 Err:<nil> Duration:6.367208ms signal:<nil>}
//	{Stdout:GO Stderr: ExitCode:0 Err:<nil> Duration:4.976291ms signal:<nil>}
// ]

func (*Cmd) Run

func (c *Cmd) Run() (Result, error)

Run executes the command and returns the result and any error. @group Execution

Example: run

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.ExitCode == 0)
// #bool true

func (*Cmd) Setpgid

func (c *Cmd) Setpgid(on bool) *Cmd

Setpgid places the child in a new process group for group signals. @group OS Controls

Example: setpgid

out, _ := execx.Command("printf", "ok").Setpgid(true).Output()
fmt.Print(out)
// ok

func (*Cmd) Setsid

func (c *Cmd) Setsid(on bool) *Cmd

Setsid starts the child in a new session, detaching it from the terminal. @group OS Controls

Example: setsid

out, _ := execx.Command("printf", "ok").Setsid(true).Output()
fmt.Print(out)
// ok

func (*Cmd) ShadowOff

func (c *Cmd) ShadowOff() *Cmd

ShadowOff disables shadow printing for this command chain, preserving configuration. @group Shadow Print

Example: shadow off

_, _ = execx.Command("printf", "hi").ShadowPrint().ShadowOff().Run()

func (*Cmd) ShadowOn

func (c *Cmd) ShadowOn() *Cmd

ShadowOn enables shadow printing using the previously configured options. @group Shadow Print

Example: shadow on

cmd := execx.Command("printf", "hi").
	ShadowPrint(execx.WithPrefix("run"))
cmd.ShadowOff()
_, _ = cmd.ShadowOn().Run()
// run > printf hi
// run > printf hi (1ms)

func (*Cmd) ShadowPrint

func (c *Cmd) ShadowPrint(opts ...ShadowOption) *Cmd

ShadowPrint configures shadow printing for this command chain. @group Shadow Print

Example: shadow print

_, _ = execx.Command("bash", "-c", `echo "hello world"`).
	ShadowPrint().
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// execx > bash -c 'echo "hello world"'
//
// hello world
//
// execx > bash -c 'echo "hello world"' (1ms)

Example: shadow print options

mask := func(cmd string) string {
	return strings.ReplaceAll(cmd, "token", "***")
}
formatter := func(ev execx.ShadowEvent) string {
	return fmt.Sprintf("shadow: %s %s", ev.Phase, ev.Command)
}
_, _ = execx.Command("bash", "-c", `echo "hello world"`).
	ShadowPrint(
		execx.WithPrefix("execx"),
		execx.WithMask(mask),
		execx.WithFormatter(formatter),
	).
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// shadow: before bash -c 'echo "hello world"'
// hello world
// shadow: after bash -c 'echo "hello world"'

func (*Cmd) ShellEscaped

func (c *Cmd) ShellEscaped() string

ShellEscaped returns a shell-escaped string for logging only. @group Debugging

Example: shell escaped

cmd := execx.Command("echo", "hello world", "it's")
fmt.Println(cmd.ShellEscaped())
// #string echo 'hello world' "it's"

func (*Cmd) Start

func (c *Cmd) Start() *Process

Start executes the command asynchronously. @group Execution

Example: start

proc := execx.Command("go", "env", "GOOS").Start()
res, _ := proc.Wait()
fmt.Println(res.ExitCode == 0)
// #bool true

func (*Cmd) StderrWriter

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

StderrWriter sets a raw writer for stderr. @group Streaming

When the writer is a terminal and no line callbacks or combined output are enabled, execx passes stderr through directly and does not buffer it for results.

Example: stderr writer

var out strings.Builder
_, err := execx.Command("go", "env", "-badflag").
	StderrWriter(&out).
	Run()
fmt.Print(out.String())
fmt.Println(err == nil)
// flag provided but not defined: -badflag
// usage: go env [-json] [-changed] [-u] [-w] [var ...]
// Run 'go help env' for details.
// false

func (*Cmd) StdinBytes

func (c *Cmd) StdinBytes(input []byte) *Cmd

StdinBytes sets stdin from bytes. @group Input

Example: stdin bytes

out, _ := execx.Command("cat").
	StdinBytes([]byte("hi")).
	Output()
fmt.Println(out)
// #string hi

func (*Cmd) StdinFile

func (c *Cmd) StdinFile(file *os.File) *Cmd

StdinFile sets stdin from a file. @group Input

Example: stdin file

file, _ := os.CreateTemp("", "execx-stdin")
_, _ = file.WriteString("hi")
_, _ = file.Seek(0, 0)
out, _ := execx.Command("cat").
	StdinFile(file).
	Output()
fmt.Println(out)
// #string hi

func (*Cmd) StdinReader

func (c *Cmd) StdinReader(reader io.Reader) *Cmd

StdinReader sets stdin from an io.Reader. @group Input

Example: stdin reader

out, _ := execx.Command("cat").
	StdinReader(strings.NewReader("hi")).
	Output()
fmt.Println(out)
// #string hi

func (*Cmd) StdinString

func (c *Cmd) StdinString(input string) *Cmd

StdinString sets stdin from a string. @group Input

Example: stdin string

out, _ := execx.Command("cat").
	StdinString("hi").
	Output()
fmt.Println(out)
// #string hi

func (*Cmd) StdoutWriter

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

StdoutWriter sets a raw writer for stdout. @group Streaming

When the writer is a terminal and no line callbacks or combined output are enabled, execx passes stdout through directly and does not buffer it for results.

Example: stdout writer

var out strings.Builder
_, _ = execx.Command("printf", "hello").
	StdoutWriter(&out).
	Run()
fmt.Print(out.String())
// hello

func (*Cmd) String

func (c *Cmd) String() string

String returns a human-readable representation of the command. @group Debugging

Example: string

cmd := execx.Command("echo", "hello world", "it's")
fmt.Println(cmd.String())
// #string echo "hello world" it's

func (*Cmd) WithContext

func (c *Cmd) WithContext(ctx context.Context) *Cmd

WithContext binds the command to a context. @group Context

Example: with context

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, _ := execx.Command("go", "env", "GOOS").WithContext(ctx).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

func (*Cmd) WithDeadline

func (c *Cmd) WithDeadline(t time.Time) *Cmd

WithDeadline binds the command to a deadline. @group Context

Example: with deadline

res, _ := execx.Command("go", "env", "GOOS").WithDeadline(time.Now().Add(2 * time.Second)).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

func (*Cmd) WithPTY added in v1.1.0

func (c *Cmd) WithPTY() *Cmd

WithPTY attaches stdout/stderr to a pseudo-terminal. @group Streaming

When enabled, stdout and stderr are merged into a single stream. OnStdout and OnStderr both receive the same lines, and Result.Stderr remains empty. Platforms without PTY support return an error when the command runs.

Example: with pty

_, _ = execx.Command("printf", "hi").
	WithPTY().
	OnStdout(func(line string) { fmt.Println(line) }).
	Run()
// hi

func (*Cmd) WithTimeout

func (c *Cmd) WithTimeout(d time.Duration) *Cmd

WithTimeout binds the command to a timeout. @group Context

Example: with timeout

res, _ := execx.Command("go", "env", "GOOS").WithTimeout(2 * time.Second).Run()
fmt.Println(res.ExitCode == 0)
// #bool true

type DecodeChain added in v0.1.0

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

DecodeChain configures typed decoding for a command.

func (*DecodeChain) FromCombined added in v0.1.0

func (d *DecodeChain) FromCombined() *DecodeChain

FromCombined decodes from combined stdout+stderr. @group Decoding

Example: decode combined

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("sh", "-c", `printf '{"name":"gopher"}'`).
	DecodeJSON().
	FromCombined().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*DecodeChain) FromStderr added in v0.1.0

func (d *DecodeChain) FromStderr() *DecodeChain

FromStderr decodes from stderr. @group Decoding

Example: decode from stderr

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("sh", "-c", `printf '{"name":"gopher"}' 1>&2`).
	DecodeJSON().
	FromStderr().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*DecodeChain) FromStdout added in v0.1.0

func (d *DecodeChain) FromStdout() *DecodeChain

FromStdout decodes from stdout (default). @group Decoding

Example: decode from stdout

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	FromStdout().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*DecodeChain) Into added in v0.1.0

func (d *DecodeChain) Into(dst any) error

Into executes the command and decodes into dst. @group Decoding

Example: decode into

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", `{"name":"gopher"}`).
	DecodeJSON().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

func (*DecodeChain) Trim added in v0.1.0

func (d *DecodeChain) Trim() *DecodeChain

Trim trims whitespace before decoding. @group Decoding

Example: decode trim

type payload struct {
	Name string `json:"name"`
}
var out payload
_ = execx.Command("printf", "  {\"name\":\"gopher\"}  ").
	DecodeJSON().
	Trim().
	Into(&out)
fmt.Println(out.Name)
// #string gopher

type Decoder added in v0.1.0

type Decoder interface {
	Decode(data []byte, dst any) error
}

Decoder decodes serialized data into a destination value.

type DecoderFunc added in v0.1.0

type DecoderFunc func(data []byte, dst any) error

DecoderFunc adapts a function to a Decoder.

func (DecoderFunc) Decode added in v0.1.0

func (f DecoderFunc) Decode(data []byte, dst any) error

Decode implements Decoder.

type ErrExec

type ErrExec struct {
	Err      error
	ExitCode int
	Signal   os.Signal
	Stderr   string
}

ErrExec reports a failure to start or an explicit execution failure.

func (ErrExec) Error

func (e ErrExec) Error() string

Error returns the wrapped error message when available. @group Errors

Example: error string

err := execx.ErrExec{Err: fmt.Errorf("boom")}
fmt.Println(err.Error())
// #string boom

func (ErrExec) Unwrap

func (e ErrExec) Unwrap() error

Unwrap exposes the underlying error. @group Errors

Example: unwrap

err := execx.ErrExec{Err: fmt.Errorf("boom")}
fmt.Println(err.Unwrap() != nil)
// #bool true

type Process

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

Process represents an asynchronously running command.

func (*Process) GracefulShutdown

func (p *Process) GracefulShutdown(sig os.Signal, timeout time.Duration) error

GracefulShutdown sends a signal and escalates to kill after the timeout. @group Process

Example: graceful shutdown

proc := execx.Command("sleep", "2").Start()
_ = proc.GracefulShutdown(os.Interrupt, 100*time.Millisecond)
res, _ := proc.Wait()
fmt.Println(res.IsSignal(os.Interrupt))
// #bool true

func (*Process) Interrupt

func (p *Process) Interrupt() error

Interrupt sends an interrupt signal to the process. @group Process

Example: interrupt

proc := execx.Command("sleep", "2").Start()
_ = proc.Interrupt()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:75.987ms signal:interrupt}

func (*Process) KillAfter

func (p *Process) KillAfter(d time.Duration)

KillAfter terminates the process after the given duration. @group Process

Example: kill after

proc := execx.Command("sleep", "2").Start()
proc.KillAfter(100 * time.Millisecond)
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:100.456ms signal:killed}

func (*Process) Send

func (p *Process) Send(sig os.Signal) error

Send sends a signal to the process. @group Process

Example: send signal

proc := execx.Command("sleep", "2").Start()
_ = proc.Send(os.Interrupt)
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:80.123ms signal:interrupt}

func (*Process) Terminate

func (p *Process) Terminate() error

Terminate kills the process immediately. @group Process

Example: terminate

proc := execx.Command("sleep", "2").Start()
_ = proc.Terminate()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout: Stderr: ExitCode:-1 Err:<nil> Duration:70.654ms signal:killed}

func (*Process) Wait

func (p *Process) Wait() (Result, error)

Wait waits for the command to complete and returns the result and any error. @group Process

Example: wait

proc := execx.Command("go", "env", "GOOS").Start()
res, _ := proc.Wait()
fmt.Printf("%+v", res)
// {Stdout:darwin
// Stderr: ExitCode:0 Err:<nil> Duration:1.234ms signal:<nil>}

type Result

type Result struct {
	Stdout   string
	Stderr   string
	ExitCode int
	Err      error
	Duration time.Duration
	// contains filtered or unexported fields
}

Result captures the outcome of a command execution.

func (Result) IsExitCode

func (r Result) IsExitCode(code int) bool

IsExitCode reports whether the exit code matches. @group Results

Example: exit code

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.IsExitCode(0))
// #bool true

func (Result) IsSignal

func (r Result) IsSignal(sig os.Signal) bool

IsSignal reports whether the command terminated due to a signal. @group Results

Example: signal

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.IsSignal(os.Interrupt))
// false

func (Result) OK

func (r Result) OK() bool

OK reports whether the command exited cleanly without errors. @group Results

Example: ok

res, _ := execx.Command("go", "env", "GOOS").Run()
fmt.Println(res.OK())
// #bool true

type ShadowEvent

type ShadowEvent struct {
	Command    string
	RawCommand string
	Phase      ShadowPhase
	Duration   time.Duration
	Async      bool
}

ShadowEvent captures details for ShadowPrint formatting.

type ShadowOption

type ShadowOption func(*shadowConfig)

ShadowOption configures ShadowPrint behavior.

func WithFormatter

func WithFormatter(fn func(ShadowEvent) string) ShadowOption

WithFormatter sets a formatter for ShadowPrint output. @group Shadow Print

Example: shadow formatter

formatter := func(ev execx.ShadowEvent) string {
	return fmt.Sprintf("shadow: %s %s", ev.Phase, ev.Command)
}
_, _ = execx.Command("printf", "hi").ShadowPrint(execx.WithFormatter(formatter)).Run()
// shadow: before printf hi
// shadow: after printf hi

func WithMask

func WithMask(fn func(string) string) ShadowOption

WithMask applies a masker to the shadow-printed command string. @group Shadow Print

Example: shadow mask

mask := func(cmd string) string {
	return strings.ReplaceAll(cmd, "secret", "***")
}
_, _ = execx.Command("printf", "secret").ShadowPrint(execx.WithMask(mask)).Run()
// execx > printf ***
// execx > printf *** (1ms)

func WithPrefix

func WithPrefix(prefix string) ShadowOption

WithPrefix sets the shadow print prefix. @group Shadow Print

Example: shadow prefix

_, _ = execx.Command("printf", "hi").ShadowPrint(execx.WithPrefix("run")).Run()
// run > printf hi
// run > printf hi (1ms)

type ShadowPhase

type ShadowPhase string

ShadowPhase describes whether the shadow print is before or after execution.

const (
	// ShadowBefore labels the pre-execution shadow print.
	ShadowBefore ShadowPhase = "before"
	// ShadowAfter labels the post-execution shadow print.
	ShadowAfter ShadowPhase = "after"
)

Jump to

Keyboard shortcuts

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