在线文档  >   Golang练习   >   执行进程

在上一个示例中,我们介绍了如何生成外部进程。我们在运行 Go 进程时需要使用外部进程来实现一些功能。有时,我们希望完全替换当前的 Go 进程为另一个(可能是非 Go 的)进程。对于这种情况,我们将使用 Go 实现的经典函数 exec

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` 的大多数使用场景。