type Cmd

  1. type Cmd struct {
  2. // Path是将要执行的命令的路径。
  3. //
  4. // 该字段不能为空,如为相对路径会相对于Dir字段。
  5. Path string
  6. // Args保管命令的参数,包括命令名作为第一个参数;如果为空切片或者nil,相当于无参数命令。
  7. //
  8. // 典型用法下,Path和Args都应被Command函数设定。
  9. Args []string
  10. // Env指定进程的环境,如为nil,则是在当前进程的环境下执行。
  11. Env []string
  12. // Dir指定命令的工作目录。如为空字符串,会在调用者的进程当前目录下执行。
  13. Dir string
  14. // Stdin指定进程的标准输入,如为nil,进程会从空设备读取(os.DevNull)
  15. Stdin io.Reader
  16. // Stdout和Stderr指定进程的标准输出和标准错误输出。
  17. //
  18. // 如果任一个为nil,Run方法会将对应的文件描述符关联到空设备(os.DevNull)
  19. //
  20. // 如果两个字段相同,同一时间最多有一个线程可以写入。
  21. Stdout io.Writer
  22. Stderr io.Writer
  23. // ExtraFiles指定额外被新进程继承的已打开文件流,不包括标准输入、标准输出、标准错误输出。
  24. // 如果本字段非nil,entry i会变成文件描述符3+i。
  25. //
  26. // BUG: 在OS X 10.6系统中,子进程可能会继承不期望的文件描述符。
  27. // http://golang.org/issue/2603
  28. ExtraFiles []*os.File
  29. // SysProcAttr保管可选的、各操作系统特定的sys执行属性。
  30. // Run方法会将它作为os.ProcAttr的Sys字段传递给os.StartProcess函数。
  31. SysProcAttr *syscall.SysProcAttr
  32. // Process是底层的,只执行一次的进程。
  33. Process *os.Process
  34. // ProcessState包含一个已经存在的进程的信息,只有在调用Wait或Run后才可用。
  35. ProcessState *os.ProcessState
  36. // 内含隐藏或非导出字段
  37. }

func Command(name string, arg …string) Cmd 函数返回一个Cmd

  1. 注意:比如"cat aaa.txt",不能写为:exec.Command("cat aaa.txt")
  2. 一定要写为:exec.Command("cat","aaa.txt") 否则报错
  3. cmd := exec.Command("tr", "a-z", "A-Z")
  4. cmd.Stdin = strings.NewReader("some input")
  5. var out bytes.Buffer
  6. cmd.Stdout = &out
  7. err := cmd.Run()
  8. if err != nil {
  9. log.Fatal(err)
  10. }
  11. fmt.Printf("in all caps: %q\n", out.String())
  1. ommand := "echo hello”
  2. cmd := exec.Command("/bin/bash", "-c", command)

func (c *Cmd) StdinPipe() (io.WriteCloser, error)

  • StdinPipe方法返回一个在命令Start后与命令标准输入关联的管道。Wait方法获知命令结束后会关闭这个管道。必要时调用者可以调用Close方法来强行关闭管道,例如命令在输入关闭后才会执行返回时需要显式关闭管道。

func (c *Cmd) StdoutPipe() (io.ReadCloser, error)

  • StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StdoutPipe方法时调用Run函数也是错误的。参见下例:

    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 (c *Cmd) StderrPipe() (io.ReadCloser, error)

  • StderrPipe方法返回一个在命令Start后与命令标准错误输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StderrPipe方法时调用Run函数也是错误的。请参照StdoutPipe的例子。

func (c *Cmd) Run() error Run执行c包含的命令,并阻塞直到完成。

  • 如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。

func (c *Cmd) Start() error

  • Start开始执行c包含的命令,但并不会等待该命令完成即返回。Wait方法会返回命令的返回状态码并在命令返回后释放相关的资源。

    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 (c *Cmd) Wait() error Wait会阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的。

  • 如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;

  • 如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。
  • 不管命令成功或失败,Wait方法会在命令返回后释放相关的资源。

func (c *Cmd) Output() ([]byte, error) 执行命令并返回标准输出的切片。

  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 (c *Cmd) CombinedOutput() ([]byte, error) 执行命令并返回标准输出和错误输出合并的切片。