A Quick Guide to Go's os/exec Package: Running External Commands and Real‑World Use Cases

This article introduces Go's built‑in os/exec package, explains its exported types and methods, demonstrates how to run commands synchronously or in the background, capture output, handle pipes, environment variables, working directories, and shows a practical case study using the tempredis library to start a Redis server programmatically.

Go Programming World
Go Programming World
Go Programming World
A Quick Guide to Go's os/exec Package: Running External Commands and Real‑World Use Cases

The Go os/exec package provides a simple way to start external programs such as redis-server, ls, or any shell command, offering functions like Command, CommandContext, Run, Start, Output, and CombinedOutput.

Typical usage starts with creating a command object, for example:

cmd := exec.Command("echo", "Hello, World!")
err := cmd.Run()

which runs the command and waits for it to finish, logging any error.

Running a command in the background uses Start followed by Wait or by reading from pipes. The Run method is equivalent to Start + Wait:

func (c *Cmd) Run() error {
    if err := c.Start(); err != nil {
        return err
    }
    return c.Wait()
}

Context‑aware execution is possible with exec.CommandContext, allowing automatic cancellation on timeout:

ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
cmd := exec.CommandContext(ctx, "sleep", "5")
if err := cmd.Run(); err != nil {
    log.Fatalf("Command failed: %v", err)
}

To capture output, use Output (stdout only) or CombinedOutput (stdout + stderr):

cmd := exec.Command("echo", "Hello, World!")
output, err := cmd.Output()
fmt.Println(string(output))

Standard streams can be redirected by assigning to cmd.Stdout and cmd.Stderr, or by using StdoutPipe, StderrPipe, and StdinPipe for custom handling, such as feeding data via an io.Reader:

cmd := exec.Command("grep", "hello")
cmd.Stdin = bytes.NewBufferString("hello world
hi there
")
output, _ := cmd.Output()
fmt.Println(string(output))

Environment variables are accessed with cmd.Environ() and set via the Env slice:

cmd := exec.Command("printenv", "ENV_VAR")
cmd.Env = append(cmd.Env, "ENV_VAR=HelloWorld")
output, _ := cmd.Output()
fmt.Println(string(output))

Pipes can be built manually using StdoutPipe and assigning the resulting reader to another command's Stdin, or by invoking a shell with bash -c to use shell operators like |:

cmd := exec.Command("bash", "-c", "echo 'hello world' | grep hello")
output, _ := cmd.Output()
fmt.Println(string(output))

The working directory is set with cmd.Dir, and exit status can be inspected via exec.ExitError after a failed Run call.

Finding an executable in the system PATH is done with exec.LookPath:

path, err := exec.LookPath("ls")
fmt.Printf("ls is available at %s
", path)

A practical example is the third‑party tempredis library, which uses os/exec to start a temporary Redis server. The library defines a Config map, a Server struct that holds an *exec.Cmd, and methods such as Start, start, ready, waitFor, Stdout, Stderr, Term, and Kill. It launches redis-server -, writes configuration via the command's stdin, and monitors stdout for readiness strings like "The server is now ready to accept connections".

In summary, os/exec is a versatile tool for process management in Go, suitable for backend services, testing, and automation tasks, and its patterns are demonstrated both in simple snippets and in a real‑world library that starts Redis instances on demand.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

redisGoprocess managementos/execexternal commandstempredis
Go Programming World
Written by

Go Programming World

Mobile version of tech blog https://jianghushinian.cn/, covering Golang, Docker, Kubernetes and beyond.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.