version: 1.10

package exec

import "os/exec"

Overview

Package exec runs external commands. It wraps os.StartProcess to make it easier
to remap stdin and stdout, connect I/O with pipes, and do other adjustments.

Unlike the “system” library call from C and other languages, the os/exec package
intentionally does not invoke the system shell and does not expand any glob
patterns or handle other expansions, pipelines, or redirections typically done
by shells. The package behaves more like C’s “exec” family of functions. To
expand glob patterns, either call the shell directly, taking care to escape any
dangerous input, or use the path/filepath package’s Glob function. To expand
environment variables, use package os’s ExpandEnv.

Note that the examples in this package assume a Unix system. They may not run on
Windows, and they do not run in the Go Playground used by golang.org and
godoc.org.

Index

Examples

Package files

exec.go exec_unix.go lp_unix.go

Variables

  1. var ErrNotFound = errors.New("executable file not found in $PATH")

ErrNotFound is the error resulting if a path search failed to find an executable
file.

func LookPath

  1. func LookPath(file string) (string, error)

LookPath searches for an executable binary named file in the directories named
by the PATH environment variable. If file contains a slash, it is tried directly
and the PATH is not consulted. The result may be an absolute path or a path
relative to the current directory.


Example:

  1. path, err := exec.LookPath("fortune")
  2. if err != nil {
  3. log.Fatal("installing fortune is in your future")
  4. }
  5. fmt.Printf("fortune is available at %s\n", path)

type Cmd

  1. type Cmd struct {
  2. // Path is the path of the command to run.
  3. //
  4. // This is the only field that must be set to a non-zero
  5. // value. If Path is relative, it is evaluated relative
  6. // to Dir.
  7. Path string
  8.  
  9. // Args holds command line arguments, including the command as Args[0].
  10. // If the Args field is empty or nil, Run uses {Path}.
  11. //
  12. // In typical use, both Path and Args are set by calling Command.
  13. Args []string
  14.  
  15. // Env specifies the environment of the process.
  16. // Each entry is of the form "key=value".
  17. // If Env is nil, the new process uses the current process's
  18. // environment.
  19. // If Env contains duplicate environment keys, only the last
  20. // value in the slice for each duplicate key is used.
  21. Env []string
  22.  
  23. // Dir specifies the working directory of the command.
  24. // If Dir is the empty string, Run runs the command in the
  25. // calling process's current directory.
  26. Dir string
  27.  
  28. // Stdin specifies the process's standard input.
  29. //
  30. // If Stdin is nil, the process reads from the null device (os.DevNull).
  31. //
  32. // If Stdin is an *os.File, the process's standard input is connected
  33. // directly to that file.
  34. //
  35. // Otherwise, during the execution of the command a separate
  36. // goroutine reads from Stdin and delivers that data to the command
  37. // over a pipe. In this case, Wait does not complete until the goroutine
  38. // stops copying, either because it has reached the end of Stdin
  39. // (EOF or a read error) or because writing to the pipe returned an error.
  40. Stdin io.Reader
  41.  
  42. // Stdout and Stderr specify the process's standard output and error.
  43. //
  44. // If either is nil, Run connects the corresponding file descriptor
  45. // to the null device (os.DevNull).
  46. //
  47. // If either is an *os.File, the corresponding output from the process
  48. // is connected directly to that file.
  49. //
  50. // Otherwise, during the execution of the command a separate goroutine
  51. // reads from the process over a pipe and delivers that data to the
  52. // corresponding Writer. In this case, Wait does not complete until the
  53. // goroutine reaches EOF or encounters an error.
  54. //
  55. // If Stdout and Stderr are the same writer, and have a type that can
  56. // be compared with ==, at most one goroutine at a time will call Write.
  57. Stdout io.Writer
  58. Stderr io.Writer
  59.  
  60. // ExtraFiles specifies additional open files to be inherited by the
  61. // new process. It does not include standard input, standard output, or
  62. // standard error. If non-nil, entry i becomes file descriptor 3+i.
  63. ExtraFiles []*os.File
  64.  
  65. // SysProcAttr holds optional, operating system-specific attributes.
  66. // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
  67. SysProcAttr *syscall.SysProcAttr
  68.  
  69. // Process is the underlying process, once started.
  70. Process *os.Process
  71.  
  72. // ProcessState contains information about an exited process,
  73. // available after a call to Wait or Run.
  74. ProcessState *os.ProcessState
  75. // contains filtered or unexported fields
  76. }

Cmd represents an external command being prepared or run.

A Cmd cannot be reused after calling its Run, Output or CombinedOutput methods.

func Command

  1. func Command(name string, arg ...string) *Cmd

Command returns the Cmd struct to execute the named program with the given
arguments.

It sets only the Path and Args in the returned structure.

If name contains no path separators, Command uses LookPath to resolve name to a
complete path if possible. Otherwise it uses name directly as Path.

The returned Cmd’s Args field is constructed from the command name followed by
the elements of arg, so arg should not include the command name itself. For
example, Command(“echo”, “hello”). Args[0] is always name, not the possibly
resolved Path.


Example:

  1. cmd := exec.Command("tr", "a-z", "A-Z")
  2. cmd.Stdin = strings.NewReader("some input")
  3. var out bytes.Buffer
  4. cmd.Stdout = &out
  5. err := cmd.Run()
  6. if err != nil {
  7. log.Fatal(err)
  8. }
  9. fmt.Printf("in all caps: %q\n", out.String())


Example:

  1. cmd := exec.Command("prog")
  2. cmd.Env = append(os.Environ(),
  3. "FOO=duplicate_value", // ignored
  4. "FOO=actual_value", // this value is used
  5. )
  6. if err := cmd.Run(); err != nil {
  7. log.Fatal(err)
  8. }

func CommandContext

  1. func CommandContext(ctx context.Context, name string, arg ...string) *Cmd

CommandContext is like Command but includes a context.

The provided context is used to kill the process (by calling os.Process.Kill) if
the context becomes done before the command completes on its own.


Example:

  1. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
  2. defer cancel()
  3. if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
  4. // This will fail after 100 milliseconds. The 5 second sleep
  5. // will be interrupted.
  6. }

func (*Cmd) CombinedOutput

  1. func (c *Cmd) CombinedOutput() ([]byte, error)

CombinedOutput runs the command and returns its combined standard output and
standard error.


Example:

  1. cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
  2. stdoutStderr, err := cmd.CombinedOutput()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. fmt.Printf("%s\n", stdoutStderr)

func (*Cmd) Output

  1. func (c *Cmd) Output() ([]byte, error)

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.


Example:

  1. out, err := exec.Command("date").Output()
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. fmt.Printf("The date is %s\n", out)

func (*Cmd) Run

  1. func (c *Cmd) Run() error

Run starts the specified command and waits for it to complete.

The returned error is nil if the command runs, has no problems copying stdin,
stdout, and stderr, and exits with a zero exit status.

If the command starts but does not complete successfully, the error is of type
*ExitError. Other error types may be returned for other situations.

If the calling goroutine has locked the operating system thread with
runtime.LockOSThread and modified any inheritable OS-level thread state (for
example, Linux or Plan 9 name spaces), the new process will inherit the caller’s
thread state.


Example:

  1. cmd := exec.Command("sleep", "1")
  2. log.Printf("Running command and waiting for it to finish...")
  3. err := cmd.Run()
  4. log.Printf("Command finished with error: %v", err)

func (*Cmd) Start

  1. func (c *Cmd) Start() error

Start starts the specified command but does not wait for it to complete.

The Wait method will return the exit code and release associated resources once
the command exits.


Example:

  1. cmd := exec.Command("sleep", "5")
  2. err := cmd.Start()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. log.Printf("Waiting for command to finish...")
  7. err = cmd.Wait()
  8. log.Printf("Command finished with error: %v", err)

func (*Cmd) StderrPipe

  1. 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.

Wait will close the pipe after seeing the command exit, so most callers need not
close the pipe themselves; however, an implication is that it is incorrect to
call Wait before all reads from the pipe have completed. For the same reason, it
is incorrect to use Run when using StderrPipe. See the StdoutPipe example for
idiomatic usage.


Example:

  1. cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
  2. stderr, err := cmd.StderrPipe()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. if err := cmd.Start(); err != nil {
  7. log.Fatal(err)
  8. }
  9. slurp, _ := ioutil.ReadAll(stderr)
  10. fmt.Printf("%s\n", slurp)
  11. if err := cmd.Wait(); err != nil {
  12. log.Fatal(err)
  13. }

func (*Cmd) StdinPipe

  1. 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. The pipe will be closed automatically after Wait sees
the command exit. A caller need only call Close to force the pipe to close
sooner. For example, if the command being run will not exit until standard input
is closed, the caller must close the pipe.


Example:

  1. cmd := exec.Command("cat")
  2. stdin, err := cmd.StdinPipe()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. go func() {
  7. defer stdin.Close()
  8. io.WriteString(stdin, "values written to stdin are passed to cmd's standard input")
  9. }()
  10. out, err := cmd.CombinedOutput()
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. fmt.Printf("%s\n", out)

func (*Cmd) StdoutPipe

  1. 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.

Wait will close the pipe after seeing the command exit, so most callers need not
close the pipe themselves; however, an implication is that it is incorrect to
call Wait before all reads from the pipe have completed. For the same reason, it
is incorrect to call Run when using StdoutPipe. See the example for idiomatic
usage.


Example:

  1. cmd := exec.Command("echo", "-n", `{"Name": "Bob", "Age": 32}`)
  2. stdout, err := cmd.StdoutPipe()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. if err := cmd.Start(); err != nil {
  7. log.Fatal(err)
  8. }
  9. var person struct {
  10. Name string
  11. Age int
  12. }
  13. if err := json.NewDecoder(stdout).Decode(&person); err != nil {
  14. log.Fatal(err)
  15. }
  16. if err := cmd.Wait(); err != nil {
  17. log.Fatal(err)
  18. }
  19. fmt.Printf("%s is %d years old\n", person.Name, person.Age)

func (*Cmd) Wait

  1. func (c *Cmd) Wait() error

Wait waits for the command to exit and waits for any copying to stdin or copying
from stdout or stderr to complete.

The command must have been started by Start.

The returned error is nil if the command runs, has no problems copying stdin,
stdout, and stderr, and exits with a zero exit status.

If the command fails to run or doesn’t complete successfully, the error is of
type *ExitError. Other error types may be returned for I/O problems.

If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits for
the respective I/O loop copying to or from the process to complete.

Wait releases any resources associated with the Cmd.

type Error

  1. type Error struct {
  2. Name string
  3. Err error
  4. }

Error records the name of a binary that failed to be executed and the reason it
failed.

func (*Error) Error

  1. func (e *Error) Error() string

type ExitError

  1. type ExitError struct {
  2. *os.ProcessState
  3.  
  4. // Stderr holds a subset of the standard error output from the
  5. // Cmd.Output method if standard error was not otherwise being
  6. // collected.
  7. //
  8. // If the error output is long, Stderr may contain only a prefix
  9. // and suffix of the output, with the middle replaced with
  10. // text about the number of omitted bytes.
  11. //
  12. // Stderr is provided for debugging, for inclusion in error messages.
  13. // Users with other needs should redirect Cmd.Stderr as needed.
  14. Stderr []byte
  15. }

An ExitError reports an unsuccessful exit by a command.

func (*ExitError) Error

  1. func (e *ExitError) Error() string