os/exec
包是Golang中用于调用执行外部命令的库
exec.Command
exec.Command()
函数用于使用给定的参数来执行名为name
的程序,返回结果是一个Cmd
指针对象。
func Command(name string, arg ...string) *Cmd
例如:执行系统命令ls -al
cmd := exec.Command("ls", "-a", "-l")
程序名称name
是一个字符串,若不包含分隔符则可通过LookPath()
函数获取命令对应的完整路径。
LookPath
LookPath()
函数用于搜索执行命令的完整路径,默认会在系统环境变量path
指定的目录中搜索可执行文件,若入参file
中带有斜杠/
则只会在当前目录下搜索。返回的完整路径或相当当前目录的相对路径。
func LookPath(file string) (string, error)
exec.Cmd
-
Cmd
指针对象表示一个正在准备或正在运行的外部命令 -
Cmd
指针对象可用于后续执行Run
、Start
等 函数
type Cmd struct {
Path string
Args []string
Env []string
Dir string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
ExtraFiles []*io.File
SysProcAttr *os.Process
Process *os.Process
ProcessState *os.ProcessState
}
字段 | 描述 |
---|---|
Path | 运行命令的路径,绝对路径或相对路径。 |
Args | 命令参数 |
Env | 进程环境,若为空则使用当前进程的环境。 |
Dir | 指定命令的工作目录,若为空则为当前调用进程所在目录。 |
Stdin | 标准输入,若为nil则进程会从null device中读取os.DevNull 。 |
Stdout | 标准输出 |
Stderr | 错误输出,若Stdin和Stdout都为空则命令运行时会将响应的文件描述符连接到od.DevNull 。 |
Process | 底层进程,只会启动一次。 |
ProcessState | 包含退出进程的信息,当进程调用Wait 或Run 是会有值。 |
执行命令
命令执行分为三种情况:
- 执行命令不返回结果
- 执行命令并返回结果,不返回
stdout
和stderr
。 - 执行命令并返回结果,返回
stdout
和stderr
。
执行命令 | 执行成败 | 返回结果 | 标准输出 | 标准错误 |
---|---|---|---|---|
cmd.Run() | Y | N | N | N |
cmd.Output() | Y | Y | Y | N |
cmd.CombinedOutput() | Y | Y | Y | Y |
cmd.Run
cmd.Run
函数会开始执行命令后,会发生阻塞等待执行结束,若命令执行成功则执行完毕返回nil
,否则执行失败产生*ExitError
类型的错误,发生错误则说明I/O存在问题。
func (c *Cmd) Run() error {
if err := c.Start(); err != nil {
return err
}
return c.Wait()
}
简单来说,只能通过cmd.Run()
返回的error
判断执行成败的状态,是获取不到任何输出结果的。
cmd.Output
cmd.Output()
可以运行命令,也能返回结果。但返回的结果只是标准输出,并不包含标准错误。
func (c *Cmd) Output() ([]byte, error)
cmd.CombinedOutput
当执行命令的目的是为了输出结果时可采用cmd.CombinedOutput()
函数,同时会返回Stdout
标准输出和Stderr
标准错误合并后(combined)的切片。
func (c *Cmd) CombinedOutput() ([]byte, error) {
if c.Stdout != nil {
return nil, errors.New("exec: Stdout already set")
}
if c.Stderr != nil {
return nil, errors.New("exec: Stderr already set")
}
var b bytes.Buffer
c.Stdout = &b
c.Stderr = &b
err := c.Run()
return b.Bytes(), err
}
网友评论