1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package exec runs external commands. It wraps os.StartProcess to make it
6 // easier to remap stdin and stdout, connect I/O with pipes, and do other
23 // Error records the name of a binary that failed to be executed
24 // and the reason it failed.
30 func (e
*Error
) Error() string {
31 return "exec: " + strconv
.Quote(e
.Name
) + ": " + e
.Err
.Error()
34 // Cmd represents an external command being prepared or run.
36 // Path is the path of the command to run.
38 // This is the only field that must be set to a non-zero
39 // value. If Path is relative, it is evaluated relative
43 // Args holds command line arguments, including the command as Args[0].
44 // If the Args field is empty or nil, Run uses {Path}.
46 // In typical use, both Path and Args are set by calling Command.
49 // Env specifies the environment of the process.
50 // If Env is nil, Run uses the current process's environment.
53 // Dir specifies the working directory of the command.
54 // If Dir is the empty string, Run runs the command in the
55 // calling process's current directory.
58 // Stdin specifies the process's standard input. If Stdin is
59 // nil, the process reads from the null device (os.DevNull).
62 // Stdout and Stderr specify the process's standard output and error.
64 // If either is nil, Run connects the corresponding file descriptor
65 // to the null device (os.DevNull).
67 // If Stdout and Stderr are the same writer, at most one
68 // goroutine at a time will call Write.
72 // ExtraFiles specifies additional open files to be inherited by the
73 // new process. It does not include standard input, standard output, or
74 // standard error. If non-nil, entry i becomes file descriptor 3+i.
76 // BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
77 // http://golang.org/issue/2603
80 // SysProcAttr holds optional, operating system-specific attributes.
81 // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
82 SysProcAttr
*syscall
.SysProcAttr
84 // Process is the underlying process, once started.
87 // ProcessState contains information about an exited process,
88 // available after a call to Wait or Run.
89 ProcessState
*os
.ProcessState
91 lookPathErr error
// LookPath error, if any.
92 finished
bool // when Wait was called
94 closeAfterStart
[]io
.Closer
95 closeAfterWait
[]io
.Closer
96 goroutine
[]func() error
97 errch
chan error
// one send per goroutine
100 // Command returns the Cmd struct to execute the named program with
101 // the given arguments.
103 // It sets only the Path and Args in the returned structure.
105 // If name contains no path separators, Command uses LookPath to
106 // resolve the path to a complete name if possible. Otherwise it uses
109 // The returned Cmd's Args field is constructed from the command name
110 // followed by the elements of arg, so arg should not include the
111 // command name itself. For example, Command("echo", "hello")
112 func Command(name
string, arg
...string) *Cmd
{
115 Args
: append([]string{name
}, arg
...),
117 if filepath
.Base(name
) == name
{
118 if lp
, err
:= LookPath(name
); err
!= nil {
119 cmd
.lookPathErr
= err
127 // interfaceEqual protects against panics from doing equality tests on
128 // two interfaces with non-comparable underlying types.
129 func interfaceEqual(a
, b
interface{}) bool {
136 func (c
*Cmd
) envv() []string {
143 func (c
*Cmd
) argv() []string {
147 return []string{c
.Path
}
150 func (c
*Cmd
) stdin() (f
*os
.File
, err error
) {
152 f
, err
= os
.Open(os
.DevNull
)
156 c
.closeAfterStart
= append(c
.closeAfterStart
, f
)
160 if f
, ok
:= c
.Stdin
.(*os
.File
); ok
{
164 pr
, pw
, err
:= os
.Pipe()
169 c
.closeAfterStart
= append(c
.closeAfterStart
, pr
)
170 c
.closeAfterWait
= append(c
.closeAfterWait
, pw
)
171 c
.goroutine
= append(c
.goroutine
, func() error
{
172 _
, err
:= io
.Copy(pw
, c
.Stdin
)
173 if err1
:= pw
.Close(); err
== nil {
181 func (c
*Cmd
) stdout() (f
*os
.File
, err error
) {
182 return c
.writerDescriptor(c
.Stdout
)
185 func (c
*Cmd
) stderr() (f
*os
.File
, err error
) {
186 if c
.Stderr
!= nil && interfaceEqual(c
.Stderr
, c
.Stdout
) {
187 return c
.childFiles
[1], nil
189 return c
.writerDescriptor(c
.Stderr
)
192 func (c
*Cmd
) writerDescriptor(w io
.Writer
) (f
*os
.File
, err error
) {
194 f
, err
= os
.OpenFile(os
.DevNull
, os
.O_WRONLY
, 0)
198 c
.closeAfterStart
= append(c
.closeAfterStart
, f
)
202 if f
, ok
:= w
.(*os
.File
); ok
{
206 pr
, pw
, err
:= os
.Pipe()
211 c
.closeAfterStart
= append(c
.closeAfterStart
, pw
)
212 c
.closeAfterWait
= append(c
.closeAfterWait
, pr
)
213 c
.goroutine
= append(c
.goroutine
, func() error
{
214 _
, err
:= io
.Copy(w
, pr
)
220 func (c
*Cmd
) closeDescriptors(closers
[]io
.Closer
) {
221 for _
, fd
:= range closers
{
226 // Run starts the specified command and waits for it to complete.
228 // The returned error is nil if the command runs, has no problems
229 // copying stdin, stdout, and stderr, and exits with a zero exit
232 // If the command fails to run or doesn't complete successfully, the
233 // error is of type *ExitError. Other error types may be
234 // returned for I/O problems.
235 func (c
*Cmd
) Run() error
{
236 if err
:= c
.Start(); err
!= nil {
242 // lookExtensions finds windows executable by its dir and path.
243 // It uses LookPath to try appropriate extensions.
244 // lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
245 func lookExtensions(path
, dir
string) (string, error
) {
246 if filepath
.Base(path
) == path
{
247 path
= filepath
.Join(".", path
)
250 return LookPath(path
)
252 if filepath
.VolumeName(path
) != "" {
253 return LookPath(path
)
255 if len(path
) > 1 && os
.IsPathSeparator(path
[0]) {
256 return LookPath(path
)
258 dirandpath
:= filepath
.Join(dir
, path
)
259 // We assume that LookPath will only add file extension.
260 lp
, err
:= LookPath(dirandpath
)
264 ext
:= strings
.TrimPrefix(lp
, dirandpath
)
265 return path
+ ext
, nil
268 // Start starts the specified command but does not wait for it to complete.
270 // The Wait method will return the exit code and release associated resources
271 // once the command exits.
272 func (c
*Cmd
) Start() error
{
273 if c
.lookPathErr
!= nil {
274 c
.closeDescriptors(c
.closeAfterStart
)
275 c
.closeDescriptors(c
.closeAfterWait
)
278 if runtime
.GOOS
== "windows" {
279 lp
, err
:= lookExtensions(c
.Path
, c
.Dir
)
281 c
.closeDescriptors(c
.closeAfterStart
)
282 c
.closeDescriptors(c
.closeAfterWait
)
287 if c
.Process
!= nil {
288 return errors
.New("exec: already started")
291 type F
func(*Cmd
) (*os
.File
, error
)
292 for _
, setupFd
:= range []F
{(*Cmd
).stdin
, (*Cmd
).stdout
, (*Cmd
).stderr
} {
293 fd
, err
:= setupFd(c
)
295 c
.closeDescriptors(c
.closeAfterStart
)
296 c
.closeDescriptors(c
.closeAfterWait
)
299 c
.childFiles
= append(c
.childFiles
, fd
)
301 c
.childFiles
= append(c
.childFiles
, c
.ExtraFiles
...)
304 c
.Process
, err
= os
.StartProcess(c
.Path
, c
.argv(), &os
.ProcAttr
{
311 c
.closeDescriptors(c
.closeAfterStart
)
312 c
.closeDescriptors(c
.closeAfterWait
)
316 c
.closeDescriptors(c
.closeAfterStart
)
318 c
.errch
= make(chan error
, len(c
.goroutine
))
319 for _
, fn
:= range c
.goroutine
{
320 go func(fn
func() error
) {
328 // An ExitError reports an unsuccessful exit by a command.
329 type ExitError
struct {
333 func (e
*ExitError
) Error() string {
334 return e
.ProcessState
.String()
337 // Wait waits for the command to exit.
338 // It must have been started by Start.
340 // The returned error is nil if the command runs, has no problems
341 // copying stdin, stdout, and stderr, and exits with a zero exit
344 // If the command fails to run or doesn't complete successfully, the
345 // error is of type *ExitError. Other error types may be
346 // returned for I/O problems.
348 // Wait releases any resources associated with the Cmd.
349 func (c
*Cmd
) Wait() error
{
350 if c
.Process
== nil {
351 return errors
.New("exec: not started")
354 return errors
.New("exec: Wait was already called")
357 state
, err
:= c
.Process
.Wait()
358 c
.ProcessState
= state
361 for _
= range c
.goroutine
{
362 if err
:= <-c
.errch
; err
!= nil && copyError
== nil {
367 c
.closeDescriptors(c
.closeAfterWait
)
371 } else if !state
.Success() {
372 return &ExitError
{state
}
378 // Output runs the command and returns its standard output.
379 func (c
*Cmd
) Output() ([]byte, error
) {
381 return nil, errors
.New("exec: Stdout already set")
386 return b
.Bytes(), err
389 // CombinedOutput runs the command and returns its combined standard
390 // output and standard error.
391 func (c
*Cmd
) CombinedOutput() ([]byte, error
) {
393 return nil, errors
.New("exec: Stdout already set")
396 return nil, errors
.New("exec: Stderr already set")
402 return b
.Bytes(), err
405 // StdinPipe returns a pipe that will be connected to the command's
406 // standard input when the command starts.
407 // The pipe will be closed automatically after Wait sees the command exit.
408 // A caller need only call Close to force the pipe to close sooner.
409 // For example, if the command being run will not exit until standard input
410 // is closed, the caller must close the pipe.
411 func (c
*Cmd
) StdinPipe() (io
.WriteCloser
, error
) {
413 return nil, errors
.New("exec: Stdin already set")
415 if c
.Process
!= nil {
416 return nil, errors
.New("exec: StdinPipe after process started")
418 pr
, pw
, err
:= os
.Pipe()
423 c
.closeAfterStart
= append(c
.closeAfterStart
, pr
)
424 wc
:= &closeOnce
{File
: pw
}
425 c
.closeAfterWait
= append(c
.closeAfterWait
, wc
)
429 type closeOnce
struct {
436 func (c
*closeOnce
) Close() error
{
441 func (c
*closeOnce
) close() {
442 c
.err
= c
.File
.Close()
445 // StdoutPipe returns a pipe that will be connected to the command's
446 // standard output when the command starts.
448 // Wait will close the pipe after seeing the command exit, so most callers
449 // need not close the pipe themselves; however, an implication is that
450 // it is incorrect to call Wait before all reads from the pipe have completed.
451 // For the same reason, it is incorrect to call Run when using StdoutPipe.
452 // See the example for idiomatic usage.
453 func (c
*Cmd
) StdoutPipe() (io
.ReadCloser
, error
) {
455 return nil, errors
.New("exec: Stdout already set")
457 if c
.Process
!= nil {
458 return nil, errors
.New("exec: StdoutPipe after process started")
460 pr
, pw
, err
:= os
.Pipe()
465 c
.closeAfterStart
= append(c
.closeAfterStart
, pw
)
466 c
.closeAfterWait
= append(c
.closeAfterWait
, pr
)
470 // StderrPipe returns a pipe that will be connected to the command's
471 // standard error when the command starts.
473 // Wait will close the pipe after seeing the command exit, so most callers
474 // need not close the pipe themselves; however, an implication is that
475 // it is incorrect to call Wait before all reads from the pipe have completed.
476 // For the same reason, it is incorrect to use Run when using StderrPipe.
477 // See the StdoutPipe example for idiomatic usage.
478 func (c
*Cmd
) StderrPipe() (io
.ReadCloser
, error
) {
480 return nil, errors
.New("exec: Stderr already set")
482 if c
.Process
!= nil {
483 return nil, errors
.New("exec: StderrPipe after process started")
485 pr
, pw
, err
:= os
.Pipe()
490 c
.closeAfterStart
= append(c
.closeAfterStart
, pw
)
491 c
.closeAfterWait
= append(c
.closeAfterWait
, pr
)