Spawning Processes {.en}

产卵过程 {.zh}

::: {.en} Sometimes our Go programs need to spawn other, non-Go processes. For example, the syntax highlighting on this site is implemented by spawning a pygmentize process from a Go program. Let’s look at a few examples of spawning processes from Go. :::

::: {.zh}

有时我们的Go程序需要产生其他非Goprocesses。例如,通过生成[pygmentize](http:// pygments,[实现](https://github.com/mmcgrana/gobyexample/blob/master/tools/generate.go),在此网站上突出显示语法。 org /)来自Go程序的过程。让我们看一下Go的产卵过程的几个例子。

:::

  1. package main
  2. import "fmt"
  3. import "io/ioutil"
  4. import "os/exec"
  5. func main() {

::: {.en} We’ll start with a simple command that takes no arguments or input and just prints something to stdout. The exec.Command helper creates an object to represent this external process. :::

::: {.zh}

我们将从一个简单的命令开始,该命令不带任何参数或输入,只打印出一些东西。 exec.Command助手创建一个对象来表示这个外部进程。

:::

  1. dateCmd := exec.Command("date")

::: {.en} .Output is another helper that handles the common case of running a command, waiting for it to finish, and collecting its output. If there were no errors, dateOut will hold bytes with the date info. :::

::: {.zh}

.Output是另一个帮助程序,它处理运行命令,等待它完成并收集其输出的常见情况。如果没有错误,dateOut将保存带有日期信息的字节。

:::

  1. dateOut, err := dateCmd.Output()
  2. if err != nil {
  3. panic(err)
  4. }
  5. fmt.Println("> date")
  6. fmt.Println(string(dateOut))

::: {.en} Next we’ll look at a slightly more involved case where we pipe data to the external process on its stdin and collect the results from its stdout. :::

::: {.zh}

接下来我们将看一个稍微复杂的案例,我们将数据传输到其stdin上的外部进程,并从stdout收集结果。

:::

  1. grepCmd := exec.Command("grep", "hello")

::: {.en} Here we explicitly grab input/output pipes, start the process, write some input to it, read the resulting output, and finally wait for the process to exit. :::

::: {.zh}

在这里,我们明确地获取输入/输出管道,启动进程,向其写入一些输入,读取结果输出,最后等待进程退出。

:::

  1. grepIn, _ := grepCmd.StdinPipe()
  2. grepOut, _ := grepCmd.StdoutPipe()
  3. grepCmd.Start()
  4. grepIn.Write([]byte("hello grepngoodbye grep"))
  5. grepIn.Close()
  6. grepBytes, _ := ioutil.ReadAll(grepOut)
  7. grepCmd.Wait()

::: {.en} We ommited error checks in the above example, but you could use the usual if err != nil pattern for all of them. We also only collect the StdoutPipe results, but you could collect the StderrPipe in exactly the same way. :::

::: {.zh}

我们在上面的例子中省略了错误检查,但你可以使用通常的if err!= nil模式。我们也只收集StdoutPipe结果,但你可以用不同的方式收集StderrPipe

:::

  1. fmt.Println("> grep hello")
  2. fmt.Println(string(grepBytes))

::: {.en} Note that when spawning commands we need to provide an explicitly delineated command and argument array, vs. being able to just pass in one command-line string. If you want to spawn a full command with a string, you can use bash‘s -c option: :::

::: {.zh}

请注意,在生成命令时,我们需要提供一个显式描述的命令和参数数组,而不能只传入一个命令行字符串。如果你想用字符串生成一个fullcommand,你可以使用bash-c选项:

:::

  1. lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
  2. lsOut, err := lsCmd.Output()
  3. if err != nil {
  4. panic(err)
  5. }
  6. fmt.Println("> ls -a -l -h")
  7. fmt.Println(string(lsOut))
  8. }

::: {.en} The spawned programs return output that is the same as if we had run them directly from the command-line. :::

::: {.zh}

生成的程序返回的输出与我们直接从命令行运行它们的输出相同。

:::

  1. $ go run spawning-processes.go
  2. > date
  3. Wed Oct 10 09:53:11 PDT 2012
  4. > grep hello
  5. hello grep
  6. > ls -a -l -h
  7. drwxr-xr-x 4 mark 136B Oct 3 16:29 .
  8. drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
  9. -rw-r--r-- 1 mark 1.3K Oct 3 16:28 spawning-processes.go