os/exec runs external programs directly, without going through a shell. It does not expand globs, pipes, or environment variables the way a shell command line would; those need path/filepath, explicit piping, or os.ExpandEnv instead.
exec.Command builds a *Cmd from a program name and its arguments, one per string, never a single shell-style command line. Output runs it and returns whatever it wrote to standard output.
cmd := exec.Command("echo", "hello", "world")
out, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
fmt.Print(string(out))If the program name has no path separators, Command resolves it against PATH the same way a shell would, using LookPath internally.
$ go run main.go
hello worldTry it
Examples
Output runs the command and hands back stdout directly; errors are usually *exec.ExitError.
cmd := exec.Command("echo", "hi")
out, err := cmd.Output()
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%q\n", string(out))"hi\n"Assigning Stdin and Stdout wires the process into any io.Reader or io.Writer, here a strings.Builder collecting the result.
cmd := exec.Command("tr", "a-z", "A-Z")
cmd.Stdin = strings.NewReader("go rocks")
var out strings.Builder
cmd.Stdout = &out
_ = cmd.Run()
fmt.Println(out.String())GO ROCKSStdoutPipe lets output be read as it arrives instead of buffered all at once; Start and Wait bracket the read loop.
cmd := exec.Command("printf", "a\\nb\\nc\\n")
stdout, _ := cmd.StdoutPipe()
_ = cmd.Start()
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
fmt.Println("line:", scanner.Text())
}
_ = cmd.Wait()line: a
line: b
line: cCommandContext ties the process lifetime to a context; a deadline that expires first kills the child automatically.
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
err := exec.CommandContext(ctx, "sleep", "5").Run()
fmt.Println(errors.Is(ctx.Err(), context.DeadlineExceeded))
fmt.Println(err != nil)true
trueCombinedOutput merges stdout and stderr into a single slice in the order the process wrote them.
cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s", out)stdout
stderrPackage-level
| Function | Description |
|---|---|
LookPath(file string) (string, error) | Searches PATH for an executable named file and returns its resolved path, or an error if none is found. |
var ErrDot error | Wrapped into a lookup error when the result would resolve to a program in the current directory; check with errors.Is(err, exec.ErrDot). |
var ErrNotFound error | Returned when LookPath can't find an executable file anywhere on PATH. |
var ErrWaitDelay error | Returned by Wait if the process exits successfully but its I/O pipes don't close before WaitDelay expires. |
Building a command
| Function | Description |
|---|---|
Command(name string, arg ...string) *Cmd exec.Command("echo", "hi") | Builds a Cmd for running name with the given arguments, resolving name via LookPath if it has no path separators. |
CommandContext(ctx context.Context, name string, arg ...string) *Cmd | Like Command, but kills the process, or calls a custom Cancel, once ctx is done. |
Cmd fields
| Function | Description |
|---|---|
Path string | Resolved path to the executable; the only field that must be set to a non-zero value. |
Args []string | Full command line, program name included as Args[0]; set automatically by Command. |
Env []string | Environment as "key=value" strings; nil means inherit the current process's environment. |
Dir string | Working directory for the command; empty means the calling process's own current directory. |
Stdin io.Reader | Source for standard input; nil connects the child to the null device. |
Stdout io.Writer | Destination for standard output; nil discards it. |
Stderr io.Writer | Destination for standard error; nil discards it. |
ExtraFiles []*os.File | Extra open files inherited by the child starting at file descriptor 3; not supported on Windows. |
SysProcAttr *syscall.SysProcAttr | OS-specific process attributes, passed through to os.StartProcess. |
Process *os.Process | The underlying OS process, populated once Start succeeds. |
ProcessState *os.ProcessState | Exit information, populated by Run or Wait once the command finishes. |
Err error | Holds a LookPath error if the initial path resolution failed. |
Cancel func() error | Called when a CommandContext command's context finishes early; defaults to killing the process. |
WaitDelay time.Duration | Caps how long Wait keeps waiting on a cancelled context or unclosed I/O pipes before forcing the process closed. |
Running and waiting
| Function | Description |
|---|---|
(*Cmd) Run() error | Starts the command and blocks until it exits, returning a *ExitError on a non-zero exit status. |
(*Cmd) Start() error | Starts the command without waiting for it to finish; Wait must be called afterward to release resources. |
(*Cmd) Wait() error | Waits for a Start-ed command to exit and for any I/O copying to complete. |
(*Cmd) Output() ([]byte, error) exec.Command("date").Output() | Runs the command and returns its standard output. |
(*Cmd) CombinedOutput() ([]byte, error) | Runs the command and returns standard output and standard error merged into one slice. |
Pipes and introspection
| Function | Description |
|---|---|
(*Cmd) StdinPipe() (io.WriteCloser, error) | Returns a pipe connected to the command's stdin once it starts; Wait closes it automatically. |
(*Cmd) StdoutPipe() (io.ReadCloser, error) | Returns a pipe connected to the command's stdout; every read must finish before calling Wait. |
(*Cmd) StderrPipe() (io.ReadCloser, error) | Returns a pipe connected to the command's stderr; every read must finish before calling Wait. |
(*Cmd) Environ() []string | Returns a copy of the environment the command would run with, as currently configured. |
(*Cmd) String() string | Returns a human-readable, debugging-only description of the command; not safe to feed to a shell. |
Error types
| Function | Description |
|---|---|
type Error struct{ Name string; Err error } | Returned by LookPath when a file can't be classified as an executable. |
(*Error) Error() string | Formats the error as the file name plus the underlying reason. |
(*Error) Unwrap() error | Returns the wrapped Err, so errors.Is and errors.As see through it. |
type ExitError struct{ *os.ProcessState; Stderr []byte } | Reports a command that ran but exited with a non-zero status; Stderr may hold a captured excerpt of the process's error output. |
(*ExitError) Error() string | Formats the error using the wrapped ProcessState's exit status. |