Go by Example 中文版: 执行进程

在前面的例子中,我们了解了生成外部进程的知识, 当我们需要在运行的 Go 流程中访问的外部流程时,便可以执行此操作。 但是有时候,我们只想用其它(也许是非 Go)的进程,来完全替代当前的 Go 进程。 这时,我们可以使用经典的 exec 函数的 Go 的实现。

package main
import (
    "os"
    "os/exec"
    "syscall"
)
func main() {

在这个例子中,我们将执行 ls 命令。 Go 要求我们提供想要执行的可执行文件的绝对路径, 所以我们将使用 exec.LookPath 找到它(应该是 /bin/ls)。

    binary, lookErr := exec.LookPath("ls")
    if lookErr != nil {
        panic(lookErr)
    }

Exec 需要的参数是切片的形式的(不是放在一起的一个大字符串)。 我们给 ls 一些基本的参数。注意,第一个参数需要是程序名。

    args := []string{"ls", "-a", "-l", "-h"}

Exec 同样需要使用环境变量。 这里我们仅提供当前的环境变量。

    env := os.Environ()

这里是真正的 syscall.Exec 调用。 如果这个调用成功,那么我们的进程将在这里结束,并被 /bin/ls -a -l -h 进程代替。 如果存在错误,那么我们将会得到一个返回值。

    execErr := syscall.Exec(binary, args, env)
    if execErr != nil {
        panic(execErr)
    }
}

当我们运行程序时,它会替换为 ls

$ go run execing-processes.go
total 16
drwxr-xr-x  4 mark 136B Oct 3 16:29 .
drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
-rw-r--r--  1 mark 1.3K Oct 3 16:28 execing-processes.go

注意 Go 没有提供 Unix 经典的 fork 函数。 一般来说,这没有问题,因为启动协程、生成进程和执行进程, 已经涵盖了 fork 的大多数使用场景。

下一个例子: 信号