Run, Pipe, and Time Out Processes

Capture a command's output, read an exit code, wire one command's stdout into another like a shell pipeline, and kill a slow command when a context deadline passes.

package main

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"os/exec"
	"time"
)

func main() {
	// 1) Run a command and capture stdout.
	out, _ := exec.Command("uname", "-s").Output()
	fmt.Printf("kernel: %s", out) // kernel: Darwin (or Linux)

	// 2) A non-zero exit surfaces as *exec.ExitError.
	err := exec.Command("false").Run()
	var ee *exec.ExitError
	if errors.As(err, &ee) {
		fmt.Println("false exited:", ee.ExitCode()) // false exited: 1
	}

	// 3) A pipeline: `ls -1 /` | `wc -l`, stdout wired to stdin.
	ls := exec.Command("ls", "-1", "/")
	wc := exec.Command("wc", "-l")
	wc.Stdin, _ = ls.StdoutPipe()
	var count bytes.Buffer
	wc.Stdout = &count
	wc.Start()
	ls.Run()
	wc.Wait()
	fmt.Print("entries in /: ", count.String())

	// 4) Timeout: the context deadline kills the process.
	ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
	defer cancel()
	err = exec.CommandContext(ctx, "sleep", "5").Run()
	fmt.Println("sleep result:", err) // sleep result: signal: killed
	fmt.Println("deadline hit:", errors.Is(ctx.Err(), context.DeadlineExceeded))
	// deadline hit: true
}

Save the code as main.go and run it:

go run main.go

Expected output:

kernel: Linux
false exited: 1
entries in /: 24
sleep result: signal: killed
deadline hit: true

kernel prints Linux or Darwin, and the entry count for / depends on your machine.

💻 Run locally

Copy the code above and run it on your machine

© 2026 ByteLearn.dev. Free courses for developers. · Privacy